Configuring Docker Container Restart Policies
What this article covers
- Available restart policies and how they work.
- Key differences between
always,unless-stopped, andon-failure. - Setting policies in Compose.
- When to use each policy.
- Common mistakes and how to avoid them.
Introduction: Configuring Docker Container Restart Policies
Production environments need containers to recover automatically after crashes, server reboots, or errors. Docker provides restart policies to control when and how often a container restarts. The wrong policy, however, can cause a broken container to loop endlessly or trigger unwanted restarts.
This article walks through using restart policies correctly.
Key terms
- Restart policy: Behavior when a container exits.
- always: Container restarts unconditionally, even after reboot.
- unless-stopped: Restarts unless the container was explicitly stopped.
- on-failure: Restarts only on non-zero exit codes.
- no: No automatic restart.
- restart_delay: Wait time between restart attempts.
- max-retries: Maximum attempts for
on-failure. - exit code: Process return value.
Available restart policies
| Policy | Behavior |
|---|---|
| no | Never restart automatically. |
| on-failure | Restart only if exit code is non-zero. |
| always | Always restart, even after server reboot. |
| unless-stopped | Always restart unless explicitly stopped. |
always
services:
app:
image: nginx
restart: always
Use this for services that must run immediately after a reboot. Note: the container will restart even after docker stop if the Docker daemon restarts.
unless-stopped
services:
app:
image: nginx
restart: unless-stopped
The best choice for most homelabs. Containers restart after a reboot, but not if explicitly stopped.
on-failure
services:
app:
image: mein-app
restart: on-failure
deploy:
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
Use this for batch jobs or applications where you don’t want restarts after successful completion.
no
services:
app:
image: mein-app
restart: "no"
For one-off tasks, testing, or debugging.
In Compose
services:
web:
image: nginx
restart: unless-stopped
db:
image: postgres
restart: always
Docker Run
docker run -d --name web --restart unless-stopped nginx
Checking restart count
docker ps -a
With docker inspect:
docker inspect --format='{{.RestartCount}}' <container>
Avoiding restart loops
- Use healthchecks.
- Set
max_attempts. - Fix the underlying issue instead of blindly retrying.
- Use
on-failureinstead ofalwaysfor flaky applications.
Example: database and app
services:
db:
image: postgres:16
restart: always
environment:
POSTGRES_PASSWORD: geheim
volumes:
- db_data:/var/lib/postgresql/data
app:
image: mein-app
restart: unless-stopped
depends_on:
- db
ports:
- "3000:3000"
volumes:
db_data:
Restart after system updates
sudo systemctl enable docker
Ensures Docker starts at boot, so containers with always or unless-stopped come up automatically.
Tips
- Use
unless-stoppedas the default for most services. - Use
alwaysfor critical infrastructure like databases. - Use
on-failurefor jobs that shouldn’t run continuously. - Never use
alwaysfor broken containers; it creates boot loops. - Monitor logs to find the cause of restarts.
- Use
depends_onto control startup order.
Common pitfalls
- always set but container won’t start: Docker daemon isn’t running at boot.
- Endless restart loop: Container crashes immediately,
alwayskeeps restarting it. - unless-stopped restarting anyway: System was rebooted, not manually stopped.
- Dependencies not ready: Database still initializing, app restarts prematurely.
- Wrong exit code: Application exits with 0, so
on-failuredoesn’t trigger.
Further reading and resources
- BotServ.de Docker Compose
- BotServ.de Docker Healthchecks
- BotServ.de Docker Logs
- BotServ.de Docker Log Rotation
FAQ: Docker Container Restarts
What’s the difference between always and unless-stopped?
always restarts even after docker stop if the daemon restarts. unless-stopped respects a prior manual stop.
Does unless-stopped restart after a reboot? Yes, as long as the container wasn’t explicitly stopped.
How do I prevent restart loops?
Use on-failure with max_attempts, or fix the underlying error.
When should I use no? For one-off jobs, tests, or debugging.
Can I set the retry delay?
Yes, in Compose with deploy.restart_policy.delay.
Sources and further reading
- Docker Restart Policies: https://docs.docker.com/config/containers/start-containers-automatically/
- Compose Restart: https://docs.docker.com/compose/compose-file/05-services/#restart
Summary: Configuring Docker Container Restart Policies
Restart policies keep containers running after crashes or reboots. For most homelabs and production setups, unless-stopped is the best choice because it restarts after reboots while respecting manual stops. Use always for critical services and on-failure for batch jobs. To avoid restart loops, combine healthchecks with max_attempts and clean error logs.


