Docker Compose mit Healthchecks und sicheren Neustarts zuverlässiger machen¶
Veröffentlicht am 4. September 2026 · Geschätzte Lesezeit: 10 Minuten
Ein laufender Container ist nicht automatisch ein einsatzbereiter Dienst. Mit einem lokalen Healthcheck erkennt Docker, ob die Anwendung im Container wirklich antwortet; depends_on kann abhängige Dienste beim Start darauf warten lassen und eine Restart-Policy startet beendete Container kontrolliert neu.[1][5] Plane etwa 30 bis 45 Minuten für Einrichtung und Fehlerprobe ein.
Voraussetzungen
- Ein Linux-Server mit Docker Engine und dem Docker-Compose-Plugin
- Ein vorhandenes Compose-Projekt mit einer
compose.yaml - Terminalzugriff auf den Projektordner
- Ein aktuelles Backup der Compose-Datei, Datenbanken und eingebundenen Volumes
1. Projektzustand und Werkzeuge prüfen¶
Wechsle in den Ordner deines Compose-Projekts. Ersetze <projektordner> durch den vollständigen Pfad zu diesem Ordner:
Zeige die installierten Versionen an:
Prüfe danach die vorhandene Konfiguration:
Der letzte Befehl muss ohne Fehler enden. Zeige außerdem alle zum Projekt gehörenden Container an:
docker compose ps listet Zustand und veröffentlichte Ports; mit --all erscheinen auch beendete Container.[10] Notiere die Namen der Dienste, die voneinander abhängen.
2. Konfiguration und Daten sichern¶
Erstelle vor jeder Änderung eine datierte Kopie der Compose-Datei:
Verwendet dein Projekt docker-compose.yml, ersetze compose.yaml in allen Sicherungs- und Rückweg-Befehlen durch diesen Dateinamen. Die Kopie sichert nur die Konfiguration. Sichere Datenbanken und Anwendungsdaten zusätzlich mit dem dokumentierten Backup-Verfahren der jeweiligen Anwendung.
Liste die eingebundenen Volumes auf, damit du keine Datenspeicher übersiehst:
Keine Volumes zum Test löschen
Verwende für diese Änderung nicht docker compose down -v. Der Parameter -v kann benannte Volumes und damit dauerhafte Anwendungsdaten entfernen.
3. Passenden Healthcheck auswählen¶
Ein Healthcheck muss eine kleine, lokale und aussagekräftige Prüfung ausführen. Geeignet sind beispielsweise eine interne HTTP-Gesundheitsroute, pg_isready bei PostgreSQL oder ein mit der Anwendung geliefertes Diagnoseprogramm. Docker führt den Befehl regelmäßig aus und unterscheidet dabei die Zustände starting, healthy und unhealthy.[8]
Prüfe zuerst, welches Werkzeug im vorhandenen Image verfügbar ist. Ersetze <dienstname> durch den Namen des zu prüfenden Compose-Dienstes:
<dienstname> steht für den Eintrag direkt unter services: in deiner compose.yaml und muss durch dessen echten Namen ersetzt werden. Eine leere Ausgabe bedeutet, dass weder curl noch wget gefunden wurde. Installiere nicht bei jedem Start ungeprüft zusätzliche Pakete in einem laufenden Container. Nutze stattdessen das Diagnoseprogramm des Images oder baue ein eigenes geprüftes Image mit dem benötigten Werkzeug.
Keine externe Abhängigkeit als allgemeinen Zustandstest verwenden
Prüfe möglichst den lokalen Dienst im selben Container. Eine entfernte Webseite, ein DNS-Dienst oder eine Cloud-API kann ausfallen, obwohl deine Anwendung fehlerfrei arbeitet. Zu breite Prüfungen erzeugen falsche Alarme und können bei automatisierter Reaktion Neustartschleifen auslösen.[6]
4. Healthcheck in Compose ergänzen¶
Das folgende Muster passt zu einer Anwendung, die im Container auf Port 8080 eine Route /health bereitstellt und bereits curl enthält:
services:
app:
image: <vorhandenes-image>
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "--fail", "--silent", "http://localhost:8080/health"]
interval: 30s
timeout: 5s
retries: 3
start_period: 40s
Ersetze <vorhandenes-image> durch das Image samt Version, das dein Dienst bereits verwendet. Ändere eine vorhandene image:-Zeile nicht nur wegen dieses Beispiels. Passe Port 8080 und Pfad /health an die interne Adresse deiner Anwendung an; der veröffentlichte Host-Port ist für die Prüfung im Container nicht maßgeblich.
Die Werte bedeuten:
testführt die lokale Prüfung ohne zusätzliche Shell aus. Exit-Code0gilt als erfolgreich, ein anderer Exit-Code als Fehler.[3]interval: 30sstartet regulär alle 30 Sekunden eine Prüfung.timeout: 5sbricht eine hängende Einzelprüfung nach fünf Sekunden ab.retries: 3verlangt drei aufeinanderfolgende Fehlschläge, bevor der Zustandunhealthywird.start_period: 40sgibt einem langsam startenden Dienst eine Schonzeit, bevor Startfehler auf die Fehlversuche angerechnet werden.[8]restart: unless-stoppedstartet einen beendeten Container wieder, außer er wurde bewusst gestoppt.[5]
Hat die Anwendung keine passende HTTP-Route, übernimm den Block nicht blind. Für PostgreSQL kann die Prüfung beispielsweise so aussehen:
services:
db:
image: postgres:18
restart: unless-stopped
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
volumes:
- db-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
interval: 10s
timeout: 10s
retries: 5
start_period: 30s
volumes:
db-data:
POSTGRES_USER, POSTGRES_PASSWORD und POSTGRES_DB müssen in deiner geschützten .env-Datei gesetzt sein. Verwende für POSTGRES_PASSWORD ein starkes eigenes Passwort und veröffentliche die Datei nicht. db-data ist der Name des dauerhaften Volumes und darf bei einer bestehenden Installation nur an deren bisherigen Volumenamen angepasst werden. Das doppelte Dollarzeichen in $${POSTGRES_USER} und $${POSTGRES_DB} verhindert die Auflösung durch Compose auf dem Host; erst die Shell im Container liest die Variablen.
5. Abhängige Dienste auf Bereitschaft warten lassen¶
Ein kurzes depends_on ordnet nur den Start; Compose wartet dabei nicht automatisch, bis die Anwendung im Container bereit ist. Mit condition: service_healthy wird der abhängige Dienst erst erstellt, nachdem der Healthcheck der Abhängigkeit erfolgreich war.[1]
Ergänze beim abhängigen Anwendungsdienst:
services:
app:
image: <app-image>
restart: unless-stopped
depends_on:
db:
condition: service_healthy
restart: true
Ersetze <app-image> durch das bereits verwendete Image samt Version. app ist hier der abhängige Dienst, db der Datenbankdienst; passe beide Namen an deine Datei an. restart: true innerhalb von depends_on bedeutet, dass Compose den abhängigen Dienst nach einer ausdrücklich von Compose ausgeführten Aktualisierung oder einem Compose-Neustart der Abhängigkeit ebenfalls neu startet.[1]
Diese restart-Angabe ist nicht dieselbe Eigenschaft wie restart: unless-stopped auf Diensteebene. Sie überwacht auch nicht dauerhaft spätere Healthcheck-Änderungen.
6. Aufgelöste Konfiguration kontrollieren¶
Lass Compose die vollständige Datei einschließlich Variablen und Standardwerten prüfen:
Kontrolliere in der Ausgabe besonders healthcheck, depends_on, die Dienstnamen und die Volumes. Zeige die für den Start benötigten Images an:
Behebe jeden Syntax-, Variablen- oder Imagefehler vor dem nächsten Schritt. Ein gültiges YAML-Dokument beweist noch nicht, dass das Prüfprogramm im Image existiert oder der gewählte Endpunkt richtig antwortet.
7. Dienste geordnet aktualisieren¶
Übernimm die Änderung im Hintergrund und warte auf laufende beziehungsweise gesunde Dienste:
docker compose up erstellt geänderte Container neu und erhält dabei eingebundene Volumes; --wait wartet auf den Zustand running oder healthy und läuft automatisch im Hintergrund.[4] Falls deine Compose-Version --wait nicht kennt, aktualisiere das Compose-Plugin oder starte zunächst ohne diese Option:
Prüfe danach den Status separat:
Kurze Unterbrechung einplanen
Geänderte Container können neu erstellt werden. Plane bei produktiven Diensten ein Wartungsfenster ein und prüfe vorher, ob Schreibvorgänge oder Datenbankmigrationen laufen.
8. Healthcheck und Protokoll prüfen¶
Zeige den Health-Zustand des Dienstes an. Ersetze <containername> durch den tatsächlichen Containernamen aus docker compose ps --all:
docker inspect liefert detaillierte Containerdaten und kann mit --format gezielt einen Teil davon ausgeben.[9] <containername> muss durch den echten Namen oder die Container-ID ersetzt werden. Achte auf Status, FailingStreak, ExitCode und Output.
Zeige zusätzlich die letzten Protokollzeilen des Dienstes. Ersetze <dienstname> wieder durch den Compose-Dienstnamen:
Rufe die Anwendung anschließend über ihren normalen Browser- oder Client-Zugang auf. Ein grüner Healthcheck ersetzt keinen Test des echten Nutzerwegs.
9. Neustartverhalten sicher testen¶
Ein Healthcheck allein beendet oder startet einen weiterhin laufenden, aber unhealthy gewordenen Container nicht neu. Restart-Policies reagieren auf beendete Container und auf dokumentierte Docker-Lebenszyklusereignisse, nicht auf den Health-Status allein.[5][6]
Prüfe die konfigurierte Policy. Ersetze <containername> durch den tatsächlichen Namen:
docker inspect --format 'Policy={{.HostConfig.RestartPolicy.Name}} Health={{if .State.Health}}{{.State.Health.Status}}{{else}}nicht-konfiguriert{{end}} Restarts={{.RestartCount}}' <containername>
Teste einen Neustart nur bei einem unkritischen oder zuvor gesicherten Dienst. Ersetze <dienstname> durch seinen Compose-Namen:
Kontrolliere danach Zustand und Logs:
Ein höherer Neustartzähler beweist nicht, dass die Anwendung korrekt arbeitet. Prüfe zusätzlich den Health-Status und den normalen Anwendungszugang.[6] Erzwinge für Datenbanken keinen Absturz und töte keine Prozesse, solange du Wiederherstellung und Konsistenz nicht sicher beurteilen kannst.
10. Risiken und Grenzen beachten¶
- Ein falscher Prüfpfad oder ein fehlendes Programm kann eine funktionierende Anwendung dauerhaft als
unhealthymarkieren. - Zu kurze Intervalle belasten den Dienst; zu kleine Timeouts und zu wenige Wiederholungen melden normale Lastspitzen als Fehler.
- Eine Restart-Policy ersetzt keine Ursachenanalyse. Wiederholte Abstürze können Fehler verdecken oder eine Neustartschleife erzeugen.
- Gesundheitsprüfungen dürfen keine Daten verändern, keine Backups starten und keine externen Kosten auslösen.
- Gib Datenbank- und Administrationsports nicht allein für einen Healthcheck nach außen frei. Die Prüfung läuft im Container und benötigt normalerweise kein zusätzliches
ports:. - Hinterlege keine Passwörter, Token oder privaten Schlüssel in
test-Befehlen. Sie können über die Containerkonfiguration sichtbar werden. - Für wichtige Dienste brauchst du weiterhin Backups und eine externe Überwachung; ein lokaler Healthcheck erkennt weder einen ausgefallenen Host noch einen unterbrochenen Netzwerkweg.
Das öffentlich auffindbare Video „Docker Healthchecks & Restart Policies Explained“ führt Healthchecks und Restart-Policies ergänzend vor.[7] Für technische Entscheidungen sind die aktuellen Docker-Quellen maßgeblich.
11. Typische Fehler beheben¶
unhealthytrotz erreichbarer Anwendung: LiesOutputmitdocker inspect. Prüfe, obcurl,wgetoder das anwendungsspezifische Programm im Image vorhanden ist und ob Port sowie Pfad intern stimmen.docker compose up -d --waitläuft in einen Fehler: Zeige zuerstdocker compose ps --all, den Health-Log und die Dienstprotokolle. Erhöhestart_periodnur, wenn der Dienst tatsächlich länger startet.- Anwendung startet vor der Datenbank: Kontrolliere, ob
condition: service_healthybeim richtigen Dienst steht und die Datenbank selbst einen Healthcheck besitzt.[1] - Container ist
unhealthy, startet aber nicht neu: Das ist bei einem weiterlaufenden Hauptprozess erwartbar. Healthcheck und Restart-Policy sind getrennte Mechanismen.[6] - Container bleibt nach manuellem Stoppen aus:
unless-stoppedrespektiert einen bewussten Stopp. Starte ihn wieder mitdocker compose up -d.[5] - Variablen im PostgreSQL-Check sind leer: Verwende im
CMD-SHELL-String$${POSTGRES_USER}statt${POSTGRES_USER}, damit Compose die Variable nicht vorzeitig auf dem Host ersetzt. - Änderung trifft den falschen Stack: Prüfe vor jedem Befehl den aktuellen Ordner und bei Bedarf
docker compose ls.
12. Rückweg durchführen¶
Zeige die angelegten Sicherungen an:
Stoppe weitere Tests und kopiere die gewünschte Sicherung zurück. Ersetze <sicherungsdatei> durch den vollständigen Namen aus der vorherigen Ausgabe:
<sicherungsdatei> steht für den Dateinamen deiner zuvor erstellten Kopie und muss vor dem Ausführen ersetzt werden. Prüfe anschließend die wiederhergestellte Datei:
Übernimm die alte Konfiguration:
Prüfe abschließend Status, Protokolle und die Anwendung. Bei beschädigten oder fehlenden Daten reicht die Compose-Sicherung nicht aus; stelle dann das anwendungsspezifische Datenbackup nach dessen dokumentiertem Verfahren wieder her.
Grundlage dieser Anleitung ist die aktuelle offizielle Docker-Anleitung zur Startreihenfolge in Compose, geprüft am 4. September 2026.[1] Ergänzend wurden die Docker-Referenzen zu Healthchecks, docker compose up, Restart-Policies und Diagnosebefehlen sowie eine aktuelle Praxisanalyse von Voxfor geprüft.[3][4][5]
Sources¶
[1] https://docs.docker.com/compose/how-tos/startup-order — Docker Docs: Control startup and shutdown order in Compose [3] https://docs.docker.com/reference/dockerfile — Docker Docs: Dockerfile reference [4] https://docs.docker.com/reference/cli/docker/compose/up — Docker Docs: docker compose up [5] https://docs.docker.com/engine/containers/start-containers-automatically — Docker Docs: Start containers automatically [6] https://www.voxfor.com/docker-unhealthy-healthcheck-status-restart-policy-main-process-exit — Voxfor: Docker Healthcheck vs Restart Policy [7] https://www.youtube.com/watch?v=CsIZy4mBM5A — YouTube: Docker Healthchecks & Restart Policies Explained [8] https://docs.docker.com/engine/containers/run — Docker Docs: Running containers – Healthchecks [9] https://docs.docker.com/reference/cli/docker/inspect — Docker Docs: docker inspect [10] https://docs.docker.com/reference/cli/docker/compose/ps — Docker Docs: docker compose ps
Fertig¶
Dein Compose-Projekt besitzt jetzt eine klar definierte Bereitschaftsprüfung, kann abhängige Dienste geordnet starten und beendete Container gemäß der gewählten Restart-Policy erneut starten. Die Funktionsprüfung ist bestanden, wenn docker compose config fehlerfrei endet, docker compose up -d --wait Exit-Code 0 liefert, docker compose ps --all die erwarteten Dienste als laufend und gesund zeigt, der normale Nutzerzugang funktioniert und ein geplanter Neustart ohne Datenverlust abgeschlossen wird.[4][10]