Maintenance

Site is under maintenance — quizzes are still available.

Go to quizzes

Set Restart Policies for Containers

Learn how to set restart policies for Docker containers: understand always, unless-stopped, on-failure, and no. Step-by-step guide with hands-on exercise, troubleshooting, and next steps.

Focus: set restart policies for containers

Sponsored

Your container's process crashes at 3 AM. You wake up to pager alerts, frantic Slack messages, and a dark deployment. The root cause? No restart policy. Your container exited, Docker did nothing, and production went down. Restart policies are your first line of defense against transient failures—they tell Docker exactly what to do when a process stops.

The problem this lesson solves

Docker containers are ephemeral by design. When the main process inside a container exits—whether from a bug, a memory spike, or a routine shutdown—the container stops. Without a restart policy, it stays stopped. This means manual intervention every time something fails, and in production, manual means downtime.

No restart policy = stopped container = angry users. Whether you're running a web server, a background worker, or a cron job, you need a way to recover automatically from predictable failures: process crashes, OOM kills, or temporary network outages.

Core concept / mental model

Think of a restart policy as an agreement between you and Docker about how to handle container exits. It's not a health check or a monitoring alert—it's a simple, declarative rule that triggers the docker start command automatically.

Three modes, one purpose

Docker provides four restart policies, but they boil down to three behavioral modes:

  • Always restart (always): The container restarts no matter why it stopped—crash, intentional stop, or even Docker daemon restart.
  • Restart unless stopped manually (unless-stopped): Like always, but Docker respects a manual docker stop. Great for services you sometimes need to pause.
  • Restart on failure (on-failure): Restarts only when the container exits with a non-zero exit code. If the process shuts down cleanly (exit code 0), no restart.
  • No restart (no): Default behavior. Docker does nothing. Container stays stopped.

Pro tip: unless-stopped is the production sweet spot—you want crashes to recover automatically, but you also want the ability to stop the container manually for maintenance without Docker overriding you.

How it works step by step

  1. Container starts with a specific restart policy set at docker run or docker create. You can also change it later with docker update.
  2. Process exits (cleanly or with an error). Docker inspects the exit code.
  3. Policy decision: - no: Stop. No restart. - always / unless-stopped: Restart regardless of exit code. - on-failure: Check exit code. If non-zero → restart. If zero → stop.
  4. Backoff delay: Docker applies an exponential backoff (starting at 100ms, doubling to max 1 minute) to prevent rapid restart loops. This protects Docker daemon from getting overwhelmed.
  5. Repeat: Process keeps restarting until the policy says stop or you manually intervene.

What "manual stop" means

docker stop sends a SIGTERM, then SIGKILL. Docker remembers that you (the user) initiated the stop. Policies like unless-stopped will not restart after a manual stop. However, always will—even after docker stop. Only docker container rm or an explicit policy change stops always containers.

Hands-on walkthrough

Let's test each policy with a simple busybox container that exits immediately. We'll use docker logs and docker ps -a to observe the behavior.

No restart (default)

docker run --name test-no --restart no busybox sleep 2
# Wait 3 seconds, then check
docker ps -a --filter name=test-no

Expected output: The container shows Exited (0) status. No restart. Docker left it stopped.

Always restart

docker run -d --name test-always --restart always busybox sleep 2
# Wait 5 seconds
docker ps -a --filter name=test-always

Expected output: The container will show Up status because it keeps restarting every 2 seconds. Let it run for a few seconds, then stop it manually:

docker stop test-always
docker ps -a --filter name=test-always

Even after docker stop, the container restarts almost immediately. You must docker rm -f to kill it.

Unless-stopped

docker run -d --name test-unless --restart unless-stopped busybox sleep 2
# Let it crash-restart. Then manual stop:
docker stop test-unless
# Wait 3 seconds, then check

Expected output: After manual stop, the container stays Exited (0)—it will not restart. This gives you control.

On-failure (exit 1)

docker run -d --name test-fail --restart on-failure:3 busybox sh -c "exit 1"
# Wait 10 seconds
docker ps -a --filter name=test-fail

Expected output: The container attempts to restart 3 times (because on-failure:3 limits retries), then stops permanently with Exited (1) status.

Pro tip: Use on-failure:N to cap retry attempts. Without a number, Docker retries indefinitely—which can burn CPU in a tight loop.

Compare options / when to choose what

Policy Exit code 0 Exit code 1+ Manual stop Best for
no No restart No restart N/A Temporary / debugging
always Restarts Restarts Restarts Critical always-on services
unless-stopped Restarts Restarts No restart Production web apps, APIs
on-failure[:max] No restart Restarts N/A Batch jobs, cron containers

When to choose what

  • unless-stopped: Your default for most production workloads. Gives you control while recovering crashes.
  • always: Use only when you must keep a container running even after a manual stop—rare but useful for system daemons.
  • on-failure: Great for scripts that fail rarely and you want exactly N retries. Works well with docker run --rm to auto-cleanup.
  • no: Fine for docker run --rm one-offs, CI jobs, or manually managed containers.

Troubleshooting & edge cases

Container restarting infinitely ("flapping")

Symptom: docker logs shows repeated failures, and the container bounces every second.

Cause: The process exits quickly with non-zero exit code, and restart is always or on-failure without a limit.

Fix: 1. Check logs: docker logs <container-name> --tail 50 to see why it fails. 2. Stop flapping: docker stop <container-name> won't work if policy is always. Use docker update --restart no <container-name> to disable restart temporarily. 3. Then stop and fix: docker stop <container-name>; docker rm <container-name>.

Changes to restart policy on a running container

You can change policy without recreating using:

docker update --restart unless-stopped my-web-app

This works for any running or stopped container (except those created with --restart always; you may need to stop and restart).

Docker daemon restart

When Docker daemon restarts, containers with always or unless-stopped are automatically started (as long as they weren't manually stopped). on-failure containers are not started—they wait until the process exits.

Multiple containers, same policy

Use docker compose for consistency. You can set common policies under deploy:

services:
  web:
    image: nginx
    deploy:
      restart_policy:
        condition: unless-stopped

What you learned & what's next

You now understand how to set restart policies for containers to ensure automated recovery from crashes. You can distinguish between the four policies (no, always, unless-stopped, on-failure), apply them with docker run and docker update, and troubleshoot flapping containers. This is a fundamental piece of running resilient containers.

Next up: Combine restart policies with health checks (HEALTHCHECK instruction) to build self-healing services that restart only when truly broken, not just when a single request fails.

Practice recap

Create a container that runs python3 -c "import time; time.sleep(3); exit(1)" with --restart on-failure:2. Check docker logs and docker ps -a to see it attempts 3 runs then stops. Then change the policy to unless-stopped using docker update and confirm it behaves differently after a manual stop.

Common mistakes

  • Using --restart always when you want to manually stop the container—Docker will restart it immediately, leaving you confused why docker stop didn't work.
  • Setting --restart on-failure without a max retries count, causing infinite restart loops when the process fails quickly with a non-zero exit code.
  • Assuming docker stop stops a container permanently—if the policy is always, the container will restart. Use docker update --restart no first.
  • Forgetting to consider Docker daemon restart behavior: on-failure containers do NOT auto-start after a daemon restart, only always and unless-stopped do.

Variations

  1. Kubernetes uses restartPolicy in Pod spec with values Always, OnFailure, Never—very similar to Docker's model.
  2. Docker Compose v3 supports restart_policy under deploy for Swarm services, or restart: always/unless-stopped/on-failure/no for simple services.

Real-world use cases

  • A Flask web API must restart automatically if the Python process crashes due to a memory leak.
  • A cron-like container runs a data sync script every hour; retry up to 3 times if it fails, but don't restart if it succeeds (exit 0).
  • A CI runner container should never restart automatically—manual restart only after debugging failures.

Key takeaways

  • Restart policies (no, always, unless-stopped, on-failure) control automatic recovery after container exits.
  • unless-stopped is the production-safe default: auto-recover crashes but respect manual docker stop.
  • Use docker update --restart <policy> <container> to change policies on a running container.
  • on-failure:N caps retries—critical for preventing infinite restart loops.
  • Docker daemon restart only restarts always and unless-stopped containers, not on-failure ones.

Sponsored

Sponsored

Discussion

Questions, corrections, and tips help everyone reading this page.

0 comments

Add a comment

Shown publicly with your comment.

Be constructive · max 4,000 characters

No comments yet — start the thread.

Related tutorials, quizzes, and articles for this topic.