Healthchecks in Docker definieren - mehr als nice-to-have
Healthchecks in Docker definieren - mehr als nice-to-have
Ein Healthcheck meldet Docker, ob ein Container wirklich funktioniert — nicht nur ob er läuft. Das ist die Grundlage für zuverlässige Abhängigkeiten und automatische Selbstheilung.
Healthcheck im Dockerfile
FROM nginx:alpine
HEALTHCHECK --interval=30s --timeout=5s --retries=3 --start-period=10s \
CMD curl -f http://localhost/ || exit 1
Optionen:
| Option | Bedeutung | Default |
|---|---|---|
| --interval | Wie oft wird geprüft | 30s |
| --timeout | Maximale Ausführungszeit des Tests | 30s |
| --retries | Fehlschläge bis unhealthy | 3 |
| --start-period | Anlaufzeit, Fehlschläge zählen nicht | 0s |
start-period ist wichtig für Dienste mit langer Startphase (JVM, komplexe Initialisierung).
Healthcheck in Docker Compose
services:
app:
image: myapp
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 15s
timeout: 5s
retries: 3
start_period: 30s
Alternativ als Shell-String:
healthcheck:
test: ["CMD-SHELL", "curl -f http://localhost:8080/health || exit 1"]
CMD führt den Befehl direkt aus. CMD-SHELL führt ihn in /bin/sh -c aus — nötig für Shell-Operatoren wie ||.
Praxisbeispiele pro Technologie
PostgreSQL:
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
interval: 10s
timeout: 5s
retries: 5
start_period: 15s
Redis:
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 3s
retries: 3
MySQL/MariaDB:
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "--silent"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
HTTP-Endpunkt:
healthcheck:
test: ["CMD-SHELL", "curl -f http://localhost:3000/health || exit 1"]
interval: 15s
timeout: 5s
retries: 3
start_period: 20s
Die drei Health-States
| Status | Bedeutung |
|---|---|
| starting | Innerhalb der start_period, Fehlschläge zählen nicht |
| healthy | Letzter Check war erfolgreich |
| unhealthy | Zu viele aufeinanderfolgende Fehlschläge |
docker ps # STATUS-Spalte zeigt (healthy) oder (unhealthy)
Warum Healthchecks mehr als nice-to-have sind
1. depends_on condition:
services:
app:
depends_on:
db:
condition: service_healthy # Funktioniert nur mit Healthcheck
2. Docker Swarm — automatischer Neustart:
Swarm ersetzt unhealthy Container automatisch durch neue Instanzen.
3. Load-Balancer:
Traefik und andere Router entfernen unhealthy Container automatisch aus der Rotation.
4. Monitoring:
docker events --filter event=health_status
Healthcheck deaktivieren
Für Container, bei denen ein Check keinen Sinn ergibt:
healthcheck:
disable: true
Oder im Dockerfile eines Basis-Images überschreiben:
HEALTHCHECK NONE
Health-Status in Skripten
# Warten bis Container healthy
while [ "$(docker inspect --format='{{.State.Health.Status}}' myapp)" != "healthy" ]; do
sleep 2
done
# Health-Status ausgeben
docker inspect --format='{{.State.Health.Status}}' myapp
# Letzter Healthcheck-Output
docker inspect --format='{{(index .State.Health.Log 0).Output}}' myapp
Ein sorgfältig definierter Healthcheck macht aus einem Container, der irgendwie läuft, einen Dienst, dessen Zustand das System kennt und auf den es verlässlich reagieren kann.