Docker Restart Policy
A configuration that tells Docker what to do when a container exits. The four policies — no, always, on-failure, and unless-stopped — determine whether Docker automatically restarts a container and under what conditions.
Docker Restart Policy — Automatic Container Recovery
What Is a Docker Restart Policy in Simple Terms?
When a container stops — either because it crashed, its process exited, or you stopped it manually — what should Docker do? Restart it immediately? Wait and retry? Leave it stopped? The restart policy answers this question.
The Four Restart Policies
no (default): Container stops -> stays stopped forever Requires manual docker start to bring it back Good for: one-off jobs, development testing on-failure: Container exits with non-zero code -> restart Container exits with code 0 -> stays stopped Good for: application services (crash = restart, intentional exit = respect it) always: Any exit -> restart (even exit code 0) Survives Docker daemon restart (starts on boot) docker stop -> restarts anyway! Good for: critical services that should never be down unless-stopped: Like always, but respects manual docker stop Crash -> restart Daemon restart -> restart (starts on boot) docker stop -> stays stopped until manually started Good for: most production servicesUsing Restart Policies
# Production service — restarts on crash, respects manual stopdocker run -d \ --name payment-api \ --restart unless-stopped \ registry.razorpay.in/payment-api:v3.1.0 # Critical service — must always be runningdocker run -d \ --name nginx \ --restart always \ nginx:1.25 # Application service — restart only on crashesdocker run -d \ --name worker \ --restart on-failure:5 \ worker-image:latest# :5 = give up after 5 consecutive failures# Prevents infinite restart loop on a broken container # One-off job — no restartdocker run \ --restart no \ --rm \ migrate-image:latest # In Docker Composeservices: api: restart: unless-stopped postgres: restart: unless-stopped migration: restart: no # run once and doneChecking Restart Count
# See how many times a container has restarteddocker inspect payment-api \ --format '{{.RestartCount}}'# 0 = healthy, never restarted# 5 = restarted 5 times — investigate why# 47 = restart loop — application is broken, fix it # See restart policy in effectdocker inspect payment-api \ --format '{{.HostConfig.RestartPolicy.Name}}'# unless-stoppedRestart Policy vs Kubernetes
Docker restart policy = Kubernetes restartPolicy Docker no = Kubernetes Never Docker on-failure = Kubernetes OnFailure Docker always = Kubernetes Always But in Kubernetes, the Deployment controller also handlesnode failures — if a node goes down, pods are rescheduledto other nodes. Docker restart policy only handlesprocess-level crashes on the same host.Common MistakeUsing
--restart alwaysfor a container with a bug that makes it crash immediately on start. Docker will restart it thousands of times per hour, generating enormous amounts of log output and consuming CPU. Always investigate the restart count — if it is above 5, fix the bug instead of letting Docker keep restarting it.
Frequently Asked Questions
What's the practical difference between always and unless-stopped that trips people up?
Both restart a crashed container automatically, but they behave differently after a manual `docker stop`: `always` will restart the container again the next time the Docker daemon restarts (e.g. after a host reboot), even though you deliberately stopped it, while `unless-stopped` remembers that you stopped it manually and leaves it stopped through a daemon restart. This distinction matters most for maintenance windows — using `always` on a container you're intentionally taking down for maintenance means a host reboot mid-maintenance can bring it back up unexpectedly.
Why is on-failure often the wrong default for a production service despite sounding sensible?
`on-failure` only restarts when the container exits with a non-zero code — if the process hangs, deadlocks, or gets OOM-killed in a way that still triggers restart-worthy behavior but exits cleanly for some reason, it won't restart. It also supports a max-retry count, which means after N failures it simply stops trying and the service stays down silently unless something else is watching. For most long-running services, `unless-stopped` combined with a proper health check (which orchestrators can act on) is the safer default.