✦ For everyone, free.

Practical knowledge for real and everyday life

Home

20.3.2.1 Restart Policy Practice

A focused guide to Restart Policy Practice, connecting core concepts with practical Docker and container operations.

Restart policy practice means understanding the four Docker restart policies in detail, knowing which one is appropriate for each type of container, configuring them correctly, and verifying they behave as expected. A container without a restart policy stops and stays stopped when its process exits — suitable for development but a reliability failure in production, where a crashed service must recover automatically.

The Four Restart Policies

no — The default. Docker never restarts the container after it exits. The container stops and remains stopped regardless of the exit code or the reason for stopping.

Use case: one-shot commands, development containers, batch jobs where you want to inspect the output after the job finishes.

docker run --rm --restart no alpine sh -c "echo done && exit 0"

(Note: --rm and --restart other than no are incompatible — --rm removes the container on exit, making restart impossible.)

always — Docker restarts the container whenever it stops, regardless of exit code. If Docker daemon restarts, containers with always policy are also restarted.

Use case: services that must always run, even if manually stopped. However, once started with always, the container restarts even after docker stop — the only way to prevent restarting is to remove the container.

docker run -d --restart always --name my-service my-image
docker stop my-service     # container stops but Docker restarts it automatically

on-failure — Docker restarts the container only when it exits with a non-zero exit code. If the container exits cleanly (exit code 0), Docker does not restart it. If Docker daemon restarts, containers with on-failure are NOT automatically restarted.

With a maximum retry count:

docker run -d --restart on-failure:5 my-image

After 5 failed restarts, Docker stops retrying. The container stays stopped. This prevents restart loops that consume resources when a container has a persistent configuration error.

Use case: workers and batch jobs that should retry on failure but not loop indefinitely; microservices where you want to distinguish between intentional shutdown (exit 0) and crash (non-zero exit).

unless-stopped — Docker restarts the container after it exits, unless it was explicitly stopped with docker stop (or docker compose stop). When the Docker daemon restarts, containers with unless-stopped restart automatically as long as they were not in a stopped state when the daemon went down.

docker run -d --restart unless-stopped --name my-api my-image
docker stop my-api         # stops; Docker does NOT restart it
# Later, host reboots — Docker daemon starts
# my-api does NOT restart (it was in stopped state)

docker start my-api        # manually start it
# Now it is running with unless-stopped policy again

Use case: the standard choice for long-running production services. unless-stopped lets operators stop services for maintenance without fighting Docker's restart mechanism.

Choosing the Right Policy

Long-running service? No no (default) Yes Need to stop for maint? Yes unless-stopped No always on-failure[:N] (for workers / jobs)

Verifying Restart Policy

docker inspect my-container --format '{{.HostConfig.RestartPolicy.Name}}'
unless-stopped

For a container with a max retry count:

docker inspect my-container --format '{{.HostConfig.RestartPolicy.Name}} max={{.HostConfig.RestartPolicy.MaximumRetryCount}}'
on-failure max=5

Observing Restart Behavior

The docker ps output shows restart counts for containers that have restarted:

docker ps
CONTAINER ID   IMAGE     STATUS                         RESTARTS
a1b2c3d4e5f6   my-app    Up 2 hours (healthy)          0
b2c3d4e5f6a1   my-worker Restarting (1) 3 seconds ago  4

A container showing Restarting and a rising RESTARTS count is in a crash loop. Check its logs:

docker logs b2c3d4e5f6a1 --tail 50

The log output from the last run often shows the crash reason. Common causes: missing environment variable, failed database connection, port already in use.

Restart Delay and Backoff

Docker applies an exponential backoff when restarting a container that keeps crashing. The wait between restarts starts at 100ms and doubles with each successive failure (100ms, 200ms, 400ms, ...) up to a maximum of 1 minute. This prevents a crash-looping container from consuming excessive CPU and I/O by restarting thousands of times per second.

The backoff resets after the container has been running successfully for 10 seconds. A container that starts successfully, runs for 11 seconds, then crashes again will restart with a 100ms delay, not the previous large delay.

Restart Policies in Docker Compose

services:
  api:
    image: my-api:latest
    restart: unless-stopped

  worker:
    image: my-worker:latest
    restart: on-failure

  db:
    image: postgres:15
    restart: unless-stopped

Restart vs Healthcheck

Restart policies and healthchecks solve different problems:

  • Restart policy responds to a process that has exited — the container has stopped.
  • Healthcheck responds to a process that is running but not functioning correctly — the container is up but serving errors.

A container can be "running" but "unhealthy" — the process is alive but the application has deadlocked, lost its database connection, or is returning 500 errors. A restart policy alone does not detect this state. The healthcheck detects it and, in orchestrated environments (Docker Swarm, Kubernetes), triggers a replacement container. In standalone Docker, a healthcheck that reports unhealthy does not cause Docker to automatically restart the container — it only changes the container's reported status. Combining healthchecks with monitoring that alerts on unhealthy containers, or using an orchestrator, is required for fully automated recovery from degraded (but not crashed) application states.

Updating a Restart Policy on a Running Container

Docker does not allow modifying a restart policy on a running container directly. The container must be updated, which requires stopping and restarting it:

docker update --restart unless-stopped my-container

docker update modifies the container's runtime configuration. For restart policy changes, this takes effect without restarting the container if it is currently running, or on the next start if it is stopped. However, for other configuration changes, the container must be recreated.