Docker Compose: Multi-Container sauber betreiben
Docker Compose praxisnah erklärt: Dienste, Netze, Volumes und Healthchecks planen, Konfiguration prüfen und Ausfälle kontrolliert testen.
Dedizierte Server, Colocation und Betriebsrisiken
Er bewertet Dedicated Server, Colocation, Speicher, Netzwerkqualität und technische Hilfe unter realen Betriebsbedingungen.
Docker Compose beschreibt mehrere Container, ihre Netzwerke, Volumes und Abhängigkeiten in einer gemeinsamen YAML-Datei. Für einen belastbaren Betrieb reicht der Startbefehl jedoch nicht: Prüfen Sie die aufgelöste Konfiguration, definieren Sie echte Healthchecks, trennen Sie dauerhafte Daten und testen Sie den Ausfallpfad vor dem ersten produktiven Einsatz.
Was Docker Compose tatsächlich leistet
Compose übersetzt eine deklarative Beschreibung in einen gemeinsamen Lebenszyklus für mehrere Dienste. Die Datei hält fest, welche Images oder Builds verwendet werden, welche Verbindungen nötig sind und welche Daten einen Containerwechsel überleben müssen. Damit wird sie zum prüfbaren Betriebsmodell und nicht bloß zur Sammlung bequemer Startbefehle.
Betrieb schlägt Prospekt. Ein Setup ist nicht deshalb belastbar, weil alle Container nach dem Start als laufend erscheinen. Entscheidend ist, ob der Webdienst seine Datenbank erreicht, ob die Daten nach einem Neustart vorhanden sind und ob Fehler sichtbar werden, bevor Nutzer sie melden.
Die wichtigsten Bausteine erfüllen unterschiedliche Aufgaben:
| Baustein | Aufgabe | Typischer Prüfpunkt |
|---|---|---|
| service | Prozess und Laufzeitkonfiguration beschreiben | Status, Protokoll und Healthcheck |
| network | Erreichbarkeit zwischen Diensten begrenzen | Dienstnamen und freigegebene Verbindungen |
| volume | Dauerhafte Daten vom Container trennen | Sicherung, Wiederherstellung und Besitzrechte |
| config oder secret | Konfiguration gezielt bereitstellen | Berechtigung, Rotation und fehlende Werte |
| depends_on | Abhängigkeitsreihenfolge ausdrücken | Bereitschaft statt bloßem Prozessstart |
Ein Dienst kann andere Dienste im gemeinsamen Netz über deren Servicenamen erreichen. Die Anwendung verbindet sich deshalb im Beispiel mit dem Hostnamen db und nicht mit einer wechselnden Containeradresse. Diese Trennung ist wichtig: Container dürfen ersetzt werden, die logische Verbindung soll stabil bleiben.
Ein kleines Setup mit klaren Grenzen
Das folgende Beispiel besteht aus einem selbst gebauten Webdienst und PostgreSQL. Es veröffentlicht nur den Webzugang am Host. Die Datenbank bleibt im internen Netz, ihre Dateien liegen in einem benannten Volume. Zugangsdaten kommen aus Umgebungsvariablen und gehören nicht fest in die Compose-Datei.
name: beispielanwendung
services:
web:
build: ./app
restart: unless-stopped
environment:
DATABASE_URL: postgres://${DB_USER}:${DB_PASSWORD}@db:5432/${DB_NAME}
depends_on:
db:
condition: service_healthy
ports:
- "127.0.0.1:8080:8080"
networks:
- backend
db:
image: postgres:17
restart: unless-stopped
environment:
POSTGRES_DB: ${DB_NAME}
POSTGRES_USER: ${DB_USER}
POSTGRES_PASSWORD: ${DB_PASSWORD}
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${DB_USER} -d ${DB_NAME}"]
interval: 10s
timeout: 5s
retries: 5
volumes:
- db_data:/var/lib/postgresql/data
networks:
- backend
networks:
backend:
internal: true
volumes:
db_data:
Die Beispielwerte sind bewusst eine Ausgangskonfiguration, keine universelle Produktionsvorgabe. Pinnen Sie Images nach Ihrer Aktualisierungsstrategie genauer, passen Sie Healthchecks an die tatsächliche Anwendung an und setzen Sie vor den Webdienst einen sauber konfigurierten Reverse Proxy, wenn er öffentlich erreichbar sein soll.
Variablen getrennt halten
Eine lokale Datei mit Umgebungsvariablen kann die Platzhalter beim Auflösen der Konfiguration füllen. Diese Datei darf nicht in die Versionsverwaltung gelangen. Auf einem gemeinsam verwalteten Server sollte der Zugriff darauf ebenso streng sein wie auf einen Datenbankzugang.
DB_NAME=app
DB_USER=app
DB_PASSWORD=hier-ein-eigenes-langes-geheimnis-setzen
Compose-Variablen sind praktisch, aber keine vollständige Geheimnisverwaltung. Wer mehrere Administratoren, automatisierte Auslieferungen oder regelmäßige Rotation hat, sollte Zugangsdaten über den dafür vorgesehenen Mechanismus der Betriebsumgebung bereitstellen. Der wichtige Punkt bleibt: Konfiguration und Geheimnisse gehören nicht in das Image.
Vor dem Start die aufgelöste Datei prüfen
Die geschriebene YAML-Datei ist nur der Eingang. Compose führt Variablenersetzung, Standardwerte und gegebenenfalls mehrere Dateien zu einem kanonischen Modell zusammen. Prüfen Sie genau dieses Ergebnis. So fallen fehlende Variablen, Einrückungsfehler und unerwartete Überschreibungen vor dem Start auf.
docker compose config --quiet
docker compose config
Der erste Befehl eignet sich als schneller Validierungsschritt. Der zweite zeigt die aufgelöste Konfiguration. Achten Sie dabei besonders auf veröffentlichte Ports, Netzzuordnung, Volume-Pfade und Werte, die versehentlich leer geblieben sind. Enthält die Ausgabe Geheimnisse, behandeln Sie auch das Prüfprotokoll entsprechend vorsichtig.
Danach kann die Anwendung gebaut und im Hintergrund gestartet werden:
docker compose up -d --build
docker compose ps
docker compose logs --tail 100 web
Der Status liefert den ersten Hinweis, die Protokolle erklären den Zustand. Ein laufender Prozess ist noch kein Funktionsnachweis. Rufen Sie einen echten Anwendungspfad auf, der die Datenbank berührt. Nur so prüfen Sie die Verbindung und nicht lediglich zwei grüne Prozesszustände.
Startreihenfolge ist noch keine Bereitschaft
Eine kurze depends_on-Angabe ordnet den Start, wartet aber nicht automatisch auf eine fachlich bereite Datenbank. Das ist ein häufiger Ausfallpfad: Der Webprozess startet, versucht sofort die Verbindung und beendet sich, während die Datenbank noch initialisiert. Ein Healthcheck mit der Bedingung service_healthy macht diese Abhängigkeit explizit.
Der Healthcheck sollte das prüfen, was der abhängige Dienst wirklich benötigt. Ein bloß offener Port kann zu wenig sein. Bei PostgreSQL zeigt pg_isready zumindest, ob der Server Verbindungen annimmt. Für den Webdienst kann ein eigener Health-Endpunkt sinnvoll sein, sofern er keine teuren Arbeiten oder Nebenwirkungen auslöst.
Fragen Sie nach dem Ausfallpfad: Was geschieht, wenn die Datenbank später neu startet, das Volume voll ist oder ein Zugangswert falsch gesetzt wurde? depends_on löst diese Betriebsfragen nicht. Wiederanlauf, Zeitlimits, Fehlerbehandlung und Alarmierung bleiben Aufgaben der Anwendung und der Umgebung.
Daten müssen den Container überleben
Container sind austauschbar. Daten sind es nicht. Das benannte Volume im Beispiel entkoppelt die PostgreSQL-Dateien vom Lebenszyklus des Datenbankcontainers. Dadurch kann das Image aktualisiert oder der Container neu erstellt werden, ohne dass die Daten bewusst im Container-Layer festgehalten werden.
Ein Volume ist jedoch noch keine Sicherung. Eine Sicherung braucht ein festgelegtes Verfahren, ein Ziel außerhalb des betroffenen Hosts, Aufbewahrungsregeln und einen getesteten Rückweg. Die Wiederherstellung ist der Beweis: Prüfen Sie sie mit einer getrennten Instanz; eine erfolgreiche Sicherungsmeldung zeigt nur, dass ein Schreibvorgang stattgefunden hat.
Beim Herunterfahren ist der Unterschied zwischen diesen Befehlen erheblich:
docker compose down
docker compose down --volumes
Der erste Befehl entfernt die von Compose verwalteten Container und Netze, lässt benannte Volumes aber grundsätzlich bestehen. Die zusätzliche Volume-Option entfernt auch diese Datenbereiche. Verwenden Sie sie nur, wenn die Daten bewusst verworfen werden dürfen oder eine geprüfte Wiederherstellung bereitsteht.
Das Netz so klein wie möglich halten
Im Beispiel ist nur der Webport an die lokale Hostadresse gebunden. Die Datenbank erhält keine veröffentlichte Host-Schnittstelle und bleibt im internen backend-Netz. Das reduziert die Angriffsfläche und macht die beabsichtigte Verbindung lesbar. Eine externe Erreichbarkeit sollte immer eine bewusste Entscheidung sein, kein Nebeneffekt kopierter YAML-Zeilen.
Für einen Internetdienst sitzt typischerweise ein Reverse Proxy vor der Anwendung. Er übernimmt TLS, Hostnamen und kontrollierte Weiterleitung. Das ändert nichts am Grundsatz: Exponieren Sie nur den notwendigen Eintrittspunkt und kontrollieren Sie zusätzlich die Firewall des Hosts. Compose-Netze ersetzen keine Host-Firewall.
Serverwahl nach Betriebsweg statt Markenliste
Compose benötigt einen Linux-Host mit passender Docker-Installation, ausreichend Ressourcen, verlässlichem Speicher und einem praktikablen Wiederherstellungsweg. Für kleine Setups kommen etwa virtuelle Server von Hetzner, netcup oder OVHcloud infrage. Die passende Wahl hängt stärker vom Fehlerbudget und Supportbedarf ab als vom Compose-Befehl.
Prüfen Sie beim Anbieter nicht nur Arbeitsspeicher und vCPU. Relevant sind außerdem Snapshot- und Sicherungswege, Netzfilter, Konsolenzugriff, Standort, Ersatz im Störungsfall sowie der Export der Daten. Reaktionszeit zählt in Minuten, wenn der einzige Host ausgefallen ist und niemand an die Wiederherstellungsdaten kommt.
Für wichtige Anwendungen bleibt ein einzelner Compose-Host ein einzelner Fehlerbereich. Compose koordiniert Container, bietet aber nicht automatisch Hochverfügbarkeit über mehrere Maschinen. Wer diesen Fehlerbereich nicht akzeptieren kann, braucht eine andere Architektur oder mindestens einen getesteten Ersatzhost und einen dokumentierten Wiederanlauf.
Wartung ohne Blindflug
Eine Aktualisierung beginnt mit einer Sicherung und einer Sichtprüfung der Änderungen. Ziehen Sie neue Images nicht unbesehen in die Produktion. Lesen Sie Versionshinweise, testen Sie Datenbankmigrationen getrennt und halten Sie einen Rückweg bereit. Bei zustandsbehafteten Diensten kann ein altes Image mit bereits migrierten Daten unvereinbar sein.
Ein nüchterner Ablauf sieht so aus:
- Sicherung erstellen und Wiederherstellungsziel prüfen.
- Aufgelöste Compose-Konfiguration kontrollieren.
- Neue Images in einer getrennten Umgebung testen.
- Wartungsfenster und Rückweg festlegen.
- Aktualisierung ausführen, Status, Protokolle und Anwendungspfad prüfen.
Zum laufenden Betrieb gehören außerdem Speicherplatz, Container-Neustarts, Health-Status und Fehlerprotokolle. Compose zeigt diese Signale, verschickt aber nicht von selbst die richtige Alarmierung. Legen Sie fest, wer ein Signal erhält und welche erste Diagnose ohne langes Suchen möglich sein muss.
Prüfplan vor dem ersten produktiven Start
- Lassen Sie docker compose config –quiet ohne Fehler durchlaufen.
- Prüfen Sie veröffentlichte Ports, Netze, Volumes und leere Variablen im aufgelösten Modell.
- Starten Sie den Stack und testen Sie einen Anwendungspfad mit Datenbankzugriff.
- Stoppen Sie die Datenbank kontrolliert und beobachten Sie Fehlerbild sowie Wiederanlauf.
- Stellen Sie eine Sicherung in einer getrennten Umgebung wieder her.
Häufige Fragen
Ist Docker Compose für den Produktivbetrieb geeignet?
Warum reicht depends_on allein nicht aus?
Soll die Datenbank einen Port am Host veröffentlichen?
Löscht docker compose down meine Daten?
Eine gute Compose-Datei bleibt überschaubar, weil jede Zeile eine betriebliche Absicht ausdrückt. Der Qualitätsnachweis folgt im Betrieb: aufgelöste Konfiguration prüfen, Bereitschaft messen, Daten wiederherstellen und den Ausfallweg beobachten. Erst wenn dieser Weg funktioniert, sind mehrere gestartete Container ein betreibbares System.
Vorbereitet von
Dedizierte Server, Colocation und Betriebsrisiken
Er bewertet Dedicated Server, Colocation, Speicher, Netzwerkqualität und technische Hilfe unter realen Betriebsbedingungen.
Geprüfte Fakten
HostScout editorial