What do restart policies control?
Quick Answer
A restart policy tells Docker whether and when to automatically restart a container after it exits, or after the Docker daemon itself restarts (e.g., following a host reboot). no (the default) never restarts automatically. on-failure[:max-retries] restarts only if the container exits with a non-zero (error) status, optionally capped at a maximum number of attempts. always restarts unconditionally, even after a clean, intentional exit, and also on daemon/host restart. unless-stopped behaves like always, except it won't restart a container that was deliberately stopped by an explicit docker stop before the daemon itself restarted.
Detailed Answer
The four restart policies
docker run --restart no myapp # default: never auto-restart
docker run --restart on-failure myapp # restart only on non-zero exit
docker run --restart on-failure:5 myapp # restart on failure, up to 5 attempts total
docker run --restart always myapp # always restart, no matter how/why it exited
docker run --restart unless-stopped myapp # like "always", but respects an explicit manual stop
no — the default, no automatic restart
If the container exits for any reason (clean exit, crash, or the daemon restarting), it simply stays stopped, requiring a manual docker start to run again. Appropriate for one-off tasks and anything you specifically want manual control over.
on-failure — restart only when something goes wrong
docker run --restart on-failure:3 myapp
Only restarts if the container's process exits with a non-zero status code (indicating an error) — a clean, intentional exit (status 0) is left alone. The optional :3 caps this at a maximum of 3 restart attempts. After that, Docker gives up and leaves the container in the Exited state, avoiding an infinite restart loop for a container that's persistently, repeatedly failing. This is conceptually similar to Kubernetes's CrashLoopBackOff handling, though Docker's own backoff/retry behavior is simpler.
always — unconditional restart, including on daemon/host restart
docker run -d --restart always myapp
Restarts the container regardless of why it stopped — even a clean, intentional exit gets restarted. Critically, always also restarts the container automatically when the Docker daemon itself restarts (e.g., after a host reboot, or dockerd being upgraded and restarted). This is what makes always the right choice for genuinely long-running services meant to be perpetually available, surviving host reboots without manual intervention.
unless-stopped — like always, but respects a deliberate manual stop
docker run -d --restart unless-stopped myapp
docker stop myapp # this container will NOT auto-restart even after a daemon/host restart,
# because it was explicitly, deliberately stopped
The key difference from always is this: if you explicitly run docker stop on a container using unless-stopped, Docker remembers that deliberate action and won't bring it back, even across a subsequent daemon restart. A container using always, by contrast, genuinely would come back even in that scenario. This is often surprising and undesired: you stopped it on purpose, and you don't necessarily want it silently reappearing after the next host reboot. This makes unless-stopped the generally safer, more intuitive default for most long-running services compared to always.
Why restart policies matter operationally
Without an appropriate restart policy, a container that crashes (an unhandled exception, an OOM kill) simply stays down until a human notices and manually restarts it. For anything expected to run continuously, this is a real, easily-avoidable availability gap. on-failure with a sensible retry cap is a reasonable default for many application containers: it auto-recovers from transient failures, but doesn't loop forever on a genuinely broken deployment. unless-stopped is the standard choice for infrastructure/support services (a reverse proxy, a database container in a simpler non-orchestrated setup) that should always be running unless someone deliberately takes them down.
The relationship to orchestrators
In a Kubernetes-managed environment, restart behavior is instead governed by the Pod's restartPolicy and the surrounding controller's reconciliation logic (see the Kubernetes stack) — Docker's own --restart flag is primarily relevant when running plain Docker or Docker Compose directly, without a higher-level orchestrator making these decisions instead.