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
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): Likealways, but Docker respects a manualdocker 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-stoppedis 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
- Container starts with a specific restart policy set at
docker runordocker create. You can also change it later withdocker update. - Process exits (cleanly or with an error). Docker inspects the exit code.
- 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. - 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.
- 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:Nto 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 withdocker run --rmto auto-cleanup.no: Fine fordocker run --rmone-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 alwayswhen you want to manually stop the container—Docker will restart it immediately, leaving you confused whydocker stopdidn't work. - Setting
--restart on-failurewithout a max retries count, causing infinite restart loops when the process fails quickly with a non-zero exit code. - Assuming
docker stopstops a container permanently—if the policy isalways, the container will restart. Usedocker update --restart nofirst. - Forgetting to consider Docker daemon restart behavior:
on-failurecontainers do NOT auto-start after a daemon restart, onlyalwaysandunless-stoppeddo.
Variations
- Kubernetes uses
restartPolicyin Pod spec with valuesAlways,OnFailure,Never—very similar to Docker's model. - Docker Compose v3 supports
restart_policyunderdeployfor Swarm services, orrestart: always/unless-stopped/on-failure/nofor 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-stoppedis the production-safe default: auto-recover crashes but respect manualdocker stop.- Use
docker update --restart <policy> <container>to change policies on a running container. on-failure:Ncaps retries—critical for preventing infinite restart loops.- Docker daemon restart only restarts
alwaysandunless-stoppedcontainers, noton-failureones.
Keep learning
Related tutorials, quizzes, and articles for this topic.
Discussion
Questions, corrections, and tips help everyone reading this page.
0 comments
Add a comment
No comments yet — start the thread.