Docker Restart Policies Explained: no, always, on-failure, unless-stopped
When should Docker restart your container? A practical guide to the four restart policies and how to choose the right one for each workload.
Published on • October 11, 2026
AI Assistant

You have deployed a container, walked away for the weekend, and come back to find it exited hours ago. Nine times out of ten the fix is a one-word flag: --restart. But the four policies behave quite differently around daemon reboots, manual stops, and crash loops — and picking the wrong one either leaves services down or resurrects containers you deliberately stopped.
The default: no
docker run -d --name api my-api:latest # restart policy: no
Without a policy, a container exits when its main process exits and stays exited. This is correct for one-off tasks (batch jobs, migrations, build steps) but wrong for anything meant to provide ongoing service. You can inspect a container’s policy with:
docker inspect --format '{{.HostConfig.RestartPolicy.Name}}' api
always: restart unconditionally
always means exactly that — the container restarts whenever it stops, including when the Docker daemon itself restarts (e.g., after a host reboot). The nuance that surprises people:
- If you manually stop the container (
docker stop api), it stays stopped until the daemon restarts or you manually start it again. At daemon restart, it comes back.
This makes always the standard policy for production services: your web server and database should survive host reboots without an operator running docker start.
docker run -d --restart=always --name web -p 80:80 nginx:alpine
on-failure[:max-retries]: only restart on error
on-failure restarts the container only if it exits with a non-zero exit code. A clean exit (code 0) is respected — the container stays down. This is the right policy for task-like processes that should be retried when they crash but should not be relaunched after completing successfully.
The optional max-retries caps the attempts:
docker run -d --restart=on-failure:5 --name importer my-importer:latest
If the container fails five times, Docker gives up and leaves it exited. Without the cap, Docker retries indefinitely (with an increasing delay between attempts).
One limitation worth knowing: on-failure does not restart the container when the daemon restarts. If the host reboots after a crash, the container stays down unless something else starts it.
unless-stopped: always, minus the surprise
unless-stopped behaves like always across daemon restarts — with one difference: if you manually stopped the container at any point, it remains stopped even after the daemon restarts, until you explicitly start it again.
That makes it ideal for services you might intentionally take offline (a maintenance-mode backend, a queue consumer you pause during deploys) without fearing a host reboot will bring them back unexpectedly.
docker run -d --restart=unless-stopped --name worker my-worker:latest
For single-host production deployments of user-facing services, unless-stopped is often the safest default.
Quick reference
| Policy | Restarts on crash (non-zero exit) | Restarts after daemon/host reboot | Restarts after docker stop + daemon restart |
|---|---|---|---|
no (default) | No | No | No |
always | Yes | Yes | Yes |
on-failure | Yes (optionally capped) | No | No |
unless-stopped | Yes | Yes (unless manually stopped) | No |
Changing a policy on a running container
Restart policy is set at container creation time. You cannot change it with docker update. The path is recreate-and-migrate:
docker stop api && docker rename api api-old
docker run -d --restart=unless-stopped --name api \
--volumes-from api-old -p 8080:8080 my-api:latest
docker rm api-old
Or, if you use Compose, set it once in your file and recreate from there:
services:
api:
image: my-api:latest
restart: unless-stopped
Gotchas worth remembering
- Restart policies don’t fix broken applications. A container in a crash loop burns CPU and logs. Use
docker psto spot theRestartingstate anddocker logsto find the real error. --rmand restart policies conflict.docker run --rmremoves the container on exit; don’t combine it with a restart policy.- PID 1 signal handling. If your main process ignores
SIGTERM,docker stopwaits out the grace period thenSIGKILLs — fine, but consider--initto reap child processes correctly. - Orchestrators supersede this. In Kubernetes,
restartPolicyon the Pod plays this role, with far more sophisticated health checking via liveness probes.
The full semantics are documented in the Docker docker run reference. Get this one flag right and your containers will quietly survive the crashes and reboots that used to page you at 3 a.m.