Docker Restart Policies im Detail: always, unless-stopped, on-failure, no
AI generated
FROM
RUN
Docker · Betrieb · Container-Lifecycle
Docker Restart Policies im Detail
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.

17 Min. Lesezeit restart policy always unless-stopped on-failure Systemd

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.

11. FAQ: Docker Restart Policies: Das Wichtigste auf einen Blick

1Was ist die Standard-Restart-Policy von Docker, wenn ich nichts angebe?
Ohne explizite Angabe verwendet Docker die Policy no. Der Container startet nach einem Absturz oder einem Neustart des Docker-Daemons nicht automatisch neu, er bleibt einfach im Zustand Exited stehen, bis ihn jemand manuell wieder startet.
2Startet ein Container mit always auch nach einem manuellen docker stop wieder?
Ja, genau das ist der Unterschied zu unless-stopped. Bei always merkt sich Docker keinen manuellen Stopp-Zustand, deshalb startet der Container beim nächsten Neustart des Docker-Daemons oder nach einem Server-Reboot wieder, selbst wenn er zuvor bewusst gestoppt wurde.
3Kann ich die Restart Policy eines laufenden Containers nachträglich ändern?
Ja, mit docker update --restart unless-stopped lässt sich die Policy ändern, ohne den Container neu erstellen zu müssen. Der Container muss dafür nicht gestoppt werden, die neue Policy gilt sofort für zukünftige Neustart-Entscheidungen.
4Was passiert mit on-failure, wenn der Container sauber mit Exit-Code 0 endet?
Dann erfolgt kein Neustart, denn on-failure reagiert ausschließlich auf einen Exit-Code ungleich null. Ein regulär beendeter Batch-Job oder ein erfolgreich abgeschlossenes Migrations-Skript bleibt einfach im Zustand Exited (0) stehen.
5Wie begrenze ich die Anzahl der Neustart-Versuche bei on-failure?
Über die Syntax on-failure:N, wobei N die maximale Anzahl der Versuche angibt, zum Beispiel --restart on-failure:5. Ohne diese Begrenzung versucht Docker unbegrenzt oft weiter, mit exponentiell wachsenden Pausen zwischen den Versuchen.
6Funktionieren Restart Policies auch, wenn der Docker-Daemon selbst neu startet?
Ja, das ist sogar einer der Hauptzwecke. Beim Start von dockerd, etwa nach einem Server-Reboot, geht Docker die Liste vorhandener Container durch und startet all jene automatisch, deren Policy und letzter Zustand das vorsehen, vorausgesetzt der Docker-Dienst selbst ist über systemctl enable docker aktiviert.
7Reagiert die Restart Policy auf einen fehlgeschlagenen Health-Check?
Nein, Health-Checks und Restart Policies sind getrennte Mechanismen. Ein Container, der laut Health-Check als unhealthy markiert ist, aber dessen Hauptprozess weiterläuft, wird von der Restart Policy nicht angefasst. Dafür braucht es zusätzliche Werkzeuge wie einen Orchestrator oder ein eigenes Supervisor-Skript.
8Welche Policy eignet sich am besten für einen Cronjob-Container?
Für Cronjob-artige Einmal-Aufgaben ist meist no oder on-failure ohne hohes Limit sinnvoll, da der Container nach getaner Arbeit regulär enden soll. Der eigentliche Zeitplan kommt dann von außen, etwa über den Host-Cron oder ein Scheduling-Tool, nicht über die Restart Policy selbst.
9Was passiert bei always mit einem Container, der in einer Endlosschleife abstürzt?
Docker versucht ihn immer wieder neu zu starten, mit ansteigenden Backoff-Pausen zwischen den Versuchen. Das verhindert eine Prozessorlast durch ständiges Neustarten in Millisekunden-Abständen, führt aber trotzdem zu einem dauerhaften Neustart-Zyklus, der in den Logs und im Monitoring auffallen sollte.
10Muss ich die Restart Policy für jeden Container in Compose einzeln setzen?
Ja, restart ist eine Einstellung pro Service in der docker-compose.yml und gilt nicht global für den gesamten Stack. Jeder Service kann eine eigene, zu seinem Zweck passende Policy erhalten, zum Beispiel unless-stopped für den Webserver und on-failure für einen begleitenden Migrations-Job.