always, unless-stopped, on-failure, no
Ein Container, der nach einem Absturz nicht neu startet, ist im Produktivbetrieb ein stiller Ausfall. Docker bietet vier Restart Policies, die auf den ersten Blick ähnlich wirken, sich in der Praxis aber deutlich unterscheiden, besonders im Zusammenspiel mit manuellen Stopps und Daemon-Neustarts.
Inhaltsverzeichnis
- 1. Warum Restart Policies überhaupt existieren
- 2. always: Bedingungsloser Neustart bei jedem Stopp
- 3. unless-stopped: always mit Gedächtnis für manuelle Stopps
- 4. on-failure: Neustart nur bei echtem Fehler
- 5. no: Die stille Standardeinstellung
- 6. Das Zusammenspiel mit Daemon- und Host-Neustarts
- 7. Restart Policies und docker compose up -d
- 8. Typische Fehler und wie man sie vermeidet
- 9. Praktische Empfehlung je Anwendungstyp
- 10. Zusammenfassung
- 11. FAQ
1. Warum Restart Policies überhaupt existieren
Container sind bewusst kurzlebig gedacht. Ein Prozess innerhalb eines Containers kann aus vielen Gründen enden: ein unbehandelter Fehler in der Anwendung, ein Out-of-Memory-Kill durch den Kernel, ein fehlgeschlagener Health-Check oder schlicht ein Bug im Code. Ohne eingebaute Neustart-Logik müsste ein externer Prozess, etwa ein Cronjob oder ein Monitoring-Skript, den Ausfall erkennen und den Container manuell wieder hochfahren. Das ist fehleranfällig und langsam, gerade bei nächtlichen Ausfällen ohne Bereitschaftsdienst.
Restart Policies verlagern diese Verantwortung in den Docker-Daemon selbst. Der Daemon beobachtet den Exit-Code und den Container-Status und entscheidet anhand der konfigurierten Policy, ob und wann ein Neustart erfolgt. Das funktioniert containerlokal, ganz ohne Orchestrator wie Kubernetes oder Swarm, und ist deshalb gerade für Single-Host-Setups mit docker run oder docker compose die erste Verteidigungslinie gegen Ausfälle.
2. always: Bedingungsloser Neustart bei jedem Stopp
Die Policy always ist die aggressivste Variante. Der Container wird nach jedem Beenden neu gestartet, unabhängig vom Exit-Code, und zusätzlich beim nächsten Start des Docker-Daemons automatisch wieder hochgefahren, etwa nach einem Server-Reboot. Das macht always zur richtigen Wahl für dauerhaft laufende Dienste wie Webserver, Datenbanken oder Reverse Proxies, bei denen ein Ausfall so kurz wie möglich sein soll.
Die Tücke liegt in dem Wort bedingungslos: Auch nach einem manuellen docker stop startet der Container beim nächsten Daemon-Neustart wieder, weil Docker sich den zuletzt gewünschten Zustand merkt. Wer einen Container mit always testweise stoppt und den Server danach neu bootet, wundert sich, warum der Container wieder läuft. Für Wartungsfenster, in denen ein Dienst bewusst unten bleiben soll, ist always deshalb ungeeignet, ohne die Policy vorher explizit zu ändern.
# Container mit always-Policy starten
docker run -d --name webserver --restart always nginx:1.27
# Policy nachträglich prüfen
docker inspect webserver --format '{{.HostConfig.RestartPolicy.Name}}'
# Ausgabe: always
# Manueller Stopp: Container bleibt gestoppt, BIS der Daemon neu startet
docker stop webserver
docker ps -a --filter name=webserver
# STATUS: Exited (0)
# Nach einem Neustart des Docker-Daemons (z.B. systemctl restart docker
# oder Server-Reboot) startet der Container automatisch wieder
3. unless-stopped: always mit Gedächtnis für manuelle Stopps
unless-stopped verhält sich fast identisch zu always, mit einem entscheidenden Unterschied: Wird der Container explizit per docker stop beendet, merkt sich Docker diesen Zustand über einen Daemon-Neustart hinweg. Bootet der Server neu, bleibt ein manuell gestoppter Container auch gestoppt, statt automatisch wieder hochzufahren. Erst ein erneutes docker start setzt ihn wieder in den aktiven Zustand, und ab dann greift die automatische Neustart-Logik wieder wie gewohnt.
In der Praxis ist unless-stopped für die meisten produktiven Langläufer die bessere Standardwahl gegenüber always, weil sie den menschlichen Willen respektiert: Ein Administrator, der einen Dienst bewusst für Wartungsarbeiten herunterfährt, erwartet nicht, dass er nach dem nächsten Server-Neustart einfach wieder da ist. Compose-Setups mit mehreren Diensten profitieren besonders davon, weil einzelne Container gezielt offline genommen werden können, ohne dass ein versehentlicher Host-Reboot sie zurückholt.
# docker-compose.yml
services:
app:
image: mironsoft/app:latest
restart: unless-stopped
ports:
- "8080:8080"
redis:
image: redis:7-alpine
restart: unless-stopped
volumes:
- redis-data:/data
volumes:
redis-data:
4. on-failure: Neustart nur bei echtem Fehler
on-failure startet einen Container ausschließlich dann neu, wenn der Prozess mit einem Exit-Code ungleich null endet, also einen Fehler signalisiert. Ein sauberer, gewollter Exit mit Code 0 löst keinen Neustart aus. Das macht on-failure zur passenden Policy für Batch-Jobs, Migrations-Skripte oder Worker-Prozesse, die nach getaner Arbeit regulär enden sollen, aber bei einem Absturz wegen eines Netzwerkfehlers oder einer nicht erreichbaren Datenbank erneut versuchen sollen.
Optional lässt sich die Anzahl der Neustart-Versuche begrenzen, um Endlosschleifen bei dauerhaft kaputten Jobs zu vermeiden. Ohne Limit versucht Docker es mit exponentiell steigenden Wartezeiten zwischen den Versuchen unbegrenzt oft weiter, was bei einem strukturell fehlerhaften Container, etwa mit falscher Konfiguration, zu einem sinnlosen Dauerschleifen-Betrieb führt, der Log-Dateien und CPU-Zeit verschwendet.
# Migrations-Job: nur bei Fehler neu starten, maximal 5 Versuche
docker run -d --name db-migration \
--restart on-failure:5 \
mironsoft/migration-runner:latest
# Bei sauberem Exit (Code 0) bleibt der Container einfach beendet
docker run --name one-shot-report --restart on-failure \
mironsoft/report-generator:latest
docker wait one-shot-report
echo $? # 0 -> kein Neustart erfolgt
5. no: Die stille Standardeinstellung
no ist die Docker-Standardeinstellung, wenn keine Restart Policy angegeben wird. Der Container startet unter keinen Umständen automatisch neu, weder nach einem Absturz noch nach einem Daemon-Neustart. Das klingt zunächst nach der unsichersten Wahl, ist aber für interaktive Container, einmalige CLI-Aufrufe oder Debugging-Sessions genau richtig, weil hier niemand einen überraschenden Neustart erwartet.
Der häufigste Fehler in der Praxis ist, no unbewusst zu verwenden, weil die Policy schlicht vergessen wurde. Ein Webserver-Container ohne restart-Flag läuft völlig normal, bis er einmal abstürzt oder der Host neu bootet, und bleibt dann stumm offline, bis jemand den Ausfall manuell bemerkt und behebt. Gerade bei docker run ohne Compose-Datei ist das Fehlen der Policy leicht zu übersehen, deshalb lohnt sich ein bewusster Blick auf jedes restart-Flag in Deploy-Skripten.
6. Das Zusammenspiel mit Daemon- und Host-Neustarts
Ein zentraler, oft übersehener Aspekt: Restart Policies wirken nicht nur bei Prozessabstürzen innerhalb eines laufenden Systems, sondern auch beim Start des Docker-Daemons selbst. Wenn der Server neu bootet oder der Dienst dockerd per systemctl restart docker neu gestartet wird, geht Docker seine Liste der Container durch und startet all jene, deren Policy und letzter Zustand das vorsehen. Für always heißt das: praktisch immer. Für unless-stopped: es sei denn, der Container wurde zuvor manuell gestoppt.
Damit dieser Mechanismus überhaupt greifen kann, muss der Docker-Daemon selbst beim Systemstart aktiviert sein, üblicherweise über systemctl enable docker. Ist der Daemon nicht aktiviert, bleiben nach einem Reboot sämtliche Container offline, egal welche Restart Policy konfiguriert ist, weil der Daemon gar nicht erst hochfährt, um sie zu starten. Diese Systemd-Ebene wird in Betriebsdokumentationen häufig vergessen, obwohl sie die Grundvoraussetzung für jede Restart Policy ist.
# Docker-Daemon dauerhaft aktivieren (Voraussetzung für alle Restart Policies)
sudo systemctl enable docker
sudo systemctl status docker
# Testen: Alle Container mit ihrer Policy auflisten
docker ps -a --format 'table {{.Names}}\t{{.Status}}'
docker inspect $(docker ps -aq) \
--format '{{.Name}}: {{.HostConfig.RestartPolicy.Name}}'
7. Restart Policies und docker compose up -d
In Compose-Umgebungen gibt es eine zusätzliche Nuance: docker compose up -d respektiert die Restart Policy beim Neustart eines bereits laufenden Stacks, aber ein docker compose down entfernt die Container vollständig, wodurch die Policy für diese Instanzen irrelevant wird. Erst der nächste docker compose up erzeugt neue Container mit der aktuell in der YAML-Datei definierten Policy. Wer die restart-Einstellung in der Compose-Datei ändert, muss die Container also neu erstellen, ein einfaches docker compose restart reicht dafür nicht aus.
Ein weiterer Punkt: Health-Checks und Restart Policies arbeiten getrennt voneinander. Ein Container, der zwar läuft, aber laut Health-Check unhealthy ist, wird von der Restart Policy nicht automatisch neu gestartet, denn aus Sicht des Docker-Daemons läuft der Prozess ja weiterhin. Wer auf fehlgeschlagene Health-Checks reagieren will, braucht zusätzliche Logik, etwa über einen Orchestrator, ein Watchtower-artiges Tool oder ein eigenes Supervisor-Skript, das den Container bei Bedarf explizit neu startet.
8. Typische Fehler und wie man sie vermeidet
Ein klassischer Fehler ist die Verwendung von always für einmalige Jobs. Ein Backup-Skript mit always startet nach jedem Durchlauf sofort wieder, selbst wenn es korrekt durchgelaufen ist, weil always keinen Unterschied zwischen erfolgreichem und fehlerhaftem Exit macht. Das Ergebnis ist ein Container, der im Sekundentakt neu startet und Ressourcen sowie Log-Speicher verschwendet, ein Muster, das Administratoren häufig erst über auffällig hohe CPU-Last entdecken.
Ebenso problematisch ist es, unless-stopped für Container zu verwenden, die absichtlich temporär sein sollen, etwa Test- oder Staging-Instanzen. Nach einem versehentlichen Server-Reboot tauchen diese Container plötzlich wieder auf und belegen Ports oder Ressourcen, die eigentlich frei sein sollten. Als Faustregel gilt: on-failure für Jobs mit klarem Enderfolgszustand, unless-stopped für dauerhafte Dienste mit gewolltem manuellem Eingriff, always nur, wenn wirklich jeder Stopp unerwünscht ist, und no für alles Interaktive und Temporäre.
9. Praktische Empfehlung je Anwendungstyp
Für einen produktiven Webserver oder eine API, die dauerhaft erreichbar sein muss, ist unless-stopped der pragmatische Standard: automatischer Neustart nach Abstürzen und Reboots, aber respektiert gewollte manuelle Stopps während Wartungsfenstern. Für kritische Infrastruktur-Container wie einen Reverse Proxy, der niemals unbeabsichtigt unten bleiben darf, kann always sinnvoller sein, kombiniert mit klarer Dokumentation, dass ein Stopp die Policy vorübergehend ändern muss.
Für Batch-Verarbeitung, Datenbank-Migrationen, Cron-artige Einmal-Jobs und CI/CD-Build-Container ist on-failure mit einem sinnvollen Versuchslimit die richtige Wahl, weil sie zwischen echtem Fehler und regulärem Ende unterscheidet. Und für alles, was interaktiv gestartet wird, etwa ein Debug-Shell-Container oder ein lokaler Entwicklungs-Container, bleibt no die richtige, weil unauffällige Wahl. Die folgende Tabelle fasst diese Entscheidung noch einmal zusammen.
| Policy | Neustart nach Absturz | Neustart nach Daemon-Neustart | Typischer Einsatzzweck |
|---|---|---|---|
| no (Standard) | Nein | Nein | Interaktive Container, Debugging, CLI-Einmalaufrufe |
| on-failure[:max] | Ja, nur bei Exit-Code != 0 | Ja, wenn zuletzt aktiv | Batch-Jobs, Migrationen, CI-Build-Container |
| unless-stopped | Ja, immer | Ja, außer manuell gestoppt | Produktive Langläufer: Webserver, APIs, Redis |
| always | Ja, immer | Ja, bedingungslos | Kritische Infrastruktur ohne akzeptierten Stillstand |
Mironsoft
Container-Infrastruktur, CI-Pipelines und Deployment-Automatisierung
Docker-Setups, die im Team und in Produktion tragfähig bleiben?
Wir prüfen bestehende Dockerfiles und Compose-Stacks auf Sicherheitslücken, aufgeblähte Images und fragile Build-Pipelines und bauen daraus eine Container-Infrastruktur, die schnell baut, sicher läuft und im Team nachvollziehbar bleibt.
Dockerfile-Review
Multi-Stage-Builds, Layer-Caching und Image-Größe systematisch optimieren.
Security-Audit
Container-Isolation, Secrets-Handling und Image-Scanning gegen echte Angriffsflächen absichern.
CI/CD-Integration
Build-Pipelines, Registries und Deployment-Strategien für reproduzierbare Releases aufbauen.
10. Zusammenfassung
Docker Restart Policies: Das Wichtigste auf einen Blick
always
Startet nach jedem Stopp und jedem Daemon-Neustart wieder, auch nach manuellem docker stop.
unless-stopped
Wie always, respektiert aber einen bewussten manuellen Stopp über Reboots hinweg.
on-failure
Nur bei Fehler-Exit-Code neu starten, ideal für Jobs mit definiertem Enderfolg.
no
Standard ohne Angabe: kein automatischer Neustart, passend für interaktive Container.