Skip to main content

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

Bash
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 services

Using Restart Policies

Bash
# Production service — restarts on crash, respects manual stop
docker run -d \
--name payment-api \
--restart unless-stopped \
registry.razorpay.in/payment-api:v3.1.0
# Critical service — must always be running
docker run -d \
--name nginx \
--restart always \
nginx:1.25
# Application service — restart only on crashes
docker 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 restart
docker run \
--restart no \
--rm \
migrate-image:latest
# In Docker Compose
services:
api:
restart: unless-stopped
postgres:
restart: unless-stopped
migration:
restart: no # run once and done

Checking Restart Count

Bash
# See how many times a container has restarted
docker 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 effect
docker inspect payment-api \
--format '{{.HostConfig.RestartPolicy.Name}}'
# unless-stopped

Restart Policy vs Kubernetes

TEXT
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 handles
node failures — if a node goes down, pods are rescheduled
to other nodes. Docker restart policy only handles
process-level crashes on the same host.
Common Mistake

Using --restart always for 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.