Introduction to Docker Restart Policies
Docker restart policies control whether containers should be automatically restarted when they exit, and under what conditions. They are essential for building resilient, self-healing containerized applications, but misusing them can lead to unexpected behaviour, disk exhaustion, or infinite crash loops.
What Are Docker Restart Policies?
đ Deploy your AI agent in 10 minutes
Managed Hermes hosting. Zero DevOps. 100M tokens/mo included.
Try it free →A restart policy is a configuration option that tells the Docker daemon what to do when a containerâs main process terminates. By default, Docker does not restart a stopped container. You can override this by setting one of the available policies at container creation or via orchestration tools like Docker Compose or Swarm.
Available Policies
- no (default): Never restart automatically. The container stays in the âexitedâ state.
- always: Always restart, regardless of exit status. The container will also restart when the Docker daemon starts (e.g., after a host reboot).
- on-failure[:max-retries]: Restart only if the exit code indicates an error (non-zero). You can optionally limit the number of consecutive retries, e.g.,
on-failure:5. - unless-stopped: Always restart unless the container was explicitly stopped by a user (
docker stop). It will restart on daemon startup, but only if it was not manually stopped beforehand.
Why Restart Policies Matter
In production, services must be highly available. Restart policies help achieve that without external process supervisors like systemd or supervisord inside the container. They enable quick recovery from transient failures, crashes due to resource limits, or intermittent network glitches. However, they can mask deeper issues: a container crashing repeatedly may go unnoticed, causing log spam, resource contention, or cascading failures. Understanding the trade-offs is critical before applying a policy blindly.
How to Apply a Restart Policy
You can set the restart policy at container creation via docker run, in a Docker Compose file, or in Docker Swarm services. Here are practical examples for each context.
Using docker run
# No automatic restart (default)
docker run -d --name my-app nginx
# Always restart
docker run -d --restart always --name my-app nginx
# Restart only on non-zero exit, up to 5 attempts
docker run -d --restart on-failure:5 --name my-app nginx
# Restart unless manually stopped
docker run -d --restart unless-stopped --name my-app nginx
Using Docker Compose
In a docker-compose.yml file, the restart policy is defined per service under the restart key. This is the simplest way to embed the policy alongside your application definition.
version: '3.8'
services:
web:
image: nginx:alpine
restart: always
ports:
- "80:80"
worker:
image: my-worker:latest
restart: on-failure:5
environment:
- QUEUE=default
For Swarm mode services, the syntax changes slightly (see the advanced section below).
Best Practices
- Choose the right policy for the role: Stateless API servers or web proxies suit
alwaysorunless-stopped. Batch jobs, one-off migrations, or dataâinitialization containers should usenooron-failurewith limited retries to avoid repeated execution. - Combine with health checks: Restarting a container doesnât guarantee it becomes functional. Use Docker
HEALTHCHECKto detect hung processes and let orchestration (or a higherâlevel tool) decide on restart. A container can be âupâ but unresponsive; health checks bridge that gap. - Set max retries for
on-failure: Prevent infinite restart loops when a non-zero exit is expected on every launch (e.g., a configuration parsing error). Usingon-failure:5gives up after 5 failures, stopping the container and preserving logs for debugging. - Use
unless-stoppedfor development and persistent services: It balances auto-recovery with manual control â you candocker stopa container for debugging without it coming back immediately, yet it survives daemon restarts. - Monitor restart counts: High restart counts indicate instability. Use
docker inspector metrics endpoints to track them and alert when they exceed a threshold. - Understand daemonâstart behaviour:
alwaysandunless-stoppedrestart containers after a Docker daemon restart (e.g., host reboot).unless-stoppedrespects a prior manual stop across reboots;alwaysdoes not â it will resurrect containers you intentionally stopped before the reboot. - Test failure scenarios: Simulate outâofâmemory kills, application panics, and network loss. Verify the policy works as expected and doesnât cause cascading failures or resource exhaustion.
Common Pitfalls
Infinite Crash Loops
With always or unless-stopped, a container that crashes immediately (nonâzero exit) is restarted endlessly. Docker applies an exponential backâoff delay between restarts (starting at 100âŻms, doubling up to 1âŻmin), but even with this backâoff, a persistent crash can still flood logs and consume CPU. Always set a maxâretry limit (on-failure:5) or implement external circuitâbreakers. Combine with health checks so that a container stuck in a crash loop eventually gets marked unhealthy.
Disk Space Exhaustion from Logs
Every restart writes new log entries. Without log rotation, a crashâlooping container can fill the host disk in hours. Always pair restart policies with logging drivers that enforce size limits, or use Dockerâs builtâin log options:
docker run -d --restart always --log-opt max-size=10m --log-opt max-file=3 my-app
Orphaned Containers After Manual Stop
Using always on a container you later want to permanently stop creates a surprise: after a Docker daemon restart (e.g., host reboot), the container comes back to life. To truly stop it you must also remove the container or change its restart policy. unless-stopped avoids this â it remembers the manual stop state across daemon restarts.
Conflicting with Orchestration Restarts
In Docker Swarm or Kubernetes, the higherâlevel orchestrator manages restarts. For Swarm services, always use deploy.restart_policy instead of the containerâlevel --restart flag. Mixing the two can lead to conflicting restart behaviours and make troubleshooting difficult.
Ignoring Exit Code Semantics
on-failure only restarts on nonâzero exit codes. If your application catches fatal signals and exits with code 0, Docker will treat that as a âsuccessfulâ termination and wonât restart it. Ensure your app exits with a nonâzero code on unexpected termination, or use always / unless-stopped when exitâcode semantics are unreliable.
Restart Policies on DataâInitialization Containers
For containers that run database migrations or seed data, using always causes repeated initialization, potentially corrupting data or causing duplicate entries. Use on-failure:0 (no retries) or simply omit the restart policy to ensure they run once and stop.
Advanced: Restart Policy in Docker Swarm
Swarm mode offers a more granular restart policy under the deploy key. It supports condition types, delay, maximum attempts, and a failure evaluation window.
version: '3.8'
services:
api:
image: my-api:stable
deploy:
restart_policy:
condition: any # 'none', 'on-failure', or 'any'
delay: 5s # Wait before restart attempt
max_attempts: 3 # Give up after 3 failures
window: 120s # Time window to evaluate failure
The condition: any behaves like always, while on-failure respects nonâzero exits. The window parameter defines how long Docker waits after a successful start before resetting the failure counter, preventing a flapping service from being prematurely declared healthy. This provides fineâgrained control that basic containerâlevel policies lack.
Monitoring and Debugging Restarts
To check the current restart policy and the number of times a container has been restarted:
# Restart count
docker inspect --format '{{.RestartCount}}' my-app
# Active restart policy
docker inspect --format '{{.State.RestartPolicy}}' my-app
High restart counts indicate instability. Integrate these metrics into your monitoring stack (Prometheus, Datadog, etc.) and set alerts. Also, centralize container logs to quickly identify crash patterns.
Conclusion
Docker restart policies are a lightweight yet powerful mechanism for keeping services alive. By choosing the appropriate policy, setting sensible retry limits, combining them with health checks and log management, you can build robust, selfâhealing containerized systems. However, blindly enabling always without understanding failure modes can turn a minor crash into a major outage. Always test your assumptions, monitor restart counts, and align restart behaviour with both your applicationâs architecture and your deployment orchestration layer. When used correctly, restart policies form the foundation of resilient container operations.