Understanding Docker Restart Policies
Docker provides a robust restart policy mechanism that controls whether and how containers should be automatically restarted when they exit or when the Docker daemon starts. This is a container-level configuration that operates independently of the exit code and can be crucial for maintaining service availability in production environments.
By default, it's not enabled.
Docker containers do not automatically restart when the system reboots or the Docker service restarts. To ensure important containers (such as Home Assistant) are always running, you can set a restart policy. The --restart=always flag tells Docker to always restart the container unless it is explicitly stopped. This is useful for services that should be highly available or run continuously.
Available Restart Policies
Docker supports several restart policy options, each with specific behavior:
| Policy | Description | Use Case |
|---|---|---|
no | Do not automatically restart the container (default) | Development environments, one-off tasks |
on-failure[:max-retries] | Restart only if container exits with non-zero status | Applications that may fail temporarily but shouldn't run indefinitely on persistent failures |
always | Always restart the container regardless of exit status | Critical services that must remain running |
unless-stopped | Always restart unless explicitly stopped by user | Production services where manual control is needed |
Technical Differences Between Policies
always vs unless-stopped: The key distinction appears when Docker daemon restarts. With always, Docker will restart the container even if it was manually stopped before daemon shutdown. With unless-stopped, a manually stopped container remains stopped after daemon restart.
Exit Code Behavior: The on-failure policy monitors the container's exit code (accessed via $? in shell or the return value of the main process). Exit code 0 indicates success and won't trigger a restart, while any non-zero exit code (1-255) will trigger the restart mechanism.
Restart Delay Algorithm: Docker implements an exponential backoff delay for restart attempts, starting at 100ms and doubling with each consecutive failure, capping at a maximum interval to prevent excessive resource consumption during persistent failures.
Compose and stacks
If you use docker-compose or Compose V2, set the restart behavior in your compose file using the restart: key (for example restart: unless-stopped). For swarm services or stacks, restart policy configuration lives under deploy.restart_policy and has different semantics; consult your compose or swarm documentation when running services in those modes.
Troubleshooting common issues
- Container explicitly stopped: If a container was stopped manually (for example with
docker stop), some restart policies will not override that explicit action. - Docker didn't start first: If Docker Desktop or the Docker service didn't start before other services, containers won't be restarted — verify Docker itself starts at boot/login.
- Crash loops: If a container repeatedly exits with errors, it may enter a rapid restart loop; inspect logs with
docker logs <container-name>and consideron-failurewith a retry limit while diagnosing the root cause. - Container recreated: Recreating or replacing a container (e.g., via
docker-compose up --force-recreate) can remove any previous restart-policy configuration.
Caveats and recommendations
--restart=always will attempt to keep a container running indefinitely, which is useful for critical services but can hide problems if a container repeatedly fails. For unstable services, consider on-failure with a maximum retry count or fix the underlying failure before applying an unconditional restart. When using system-level supervisors or orchestrators, coordinate restart settings to avoid conflicting behavior.
Setting Restart Policies
Restart policies can be configured at container creation or updated on running containers. The policy is stored in the container's configuration and persists across Docker daemon restarts.
At Container Creation
You can set the restart policy when creating a container:
1# Example: create a container with restart policy2
3docker run -d --restart=always --name homeassistant homeassistant/home-assistant:latestOr update an existing container:
1docker update --restart=always homeassistantAdditional Configuration Examples
Here are more examples demonstrating different restart policy scenarios:
1# Restart only on failure, with maximum 5 retry attempts2docker run -d --restart=on-failure:5 --name web-app nginx:alpine3
4# Unless-stopped policy (survives manual stops across daemon restarts)5docker run -d --restart=unless-stopped --name database postgres:156
7# No restart policy (default)8docker run -d --restart=no --name temporary-worker worker:latestVerifying Restart Policy
You can inspect a container's current restart policy using Docker inspect:
1# View restart policy details2docker inspect --format='{{.HostConfig.RestartPolicy}}' homeassistant3
4# Output example: {always 0}5# Format: {PolicyName MaximumRetryCount}Restart Policy in Practice
Monitoring Restart Behavior
Docker tracks restart attempts and timing information that can be inspected:
1# View container restart count2docker inspect --format='{{.RestartCount}}' homeassistant3
4# View last start time5docker inspect --format='{{.State.StartedAt}}' homeassistant6
7# Check if container was restarted by policy8docker inspect --format='{{.State.Status}} (Restarting: {{.State.Restarting}})' homeassistantTesting Restart Policies
You can test restart behavior by simulating failures:
1# Force container to exit with error code2docker exec homeassistant /bin/sh -c "exit 1"3
4# Watch restart behavior in real-time5watch -n 1 'docker ps -a --filter name=homeassistant --format "table {{.Names}}\t{{.Status}}\t{{.State}}"'6
7# View restart attempts in logs8docker logs --tail 50 homeassistantSystem-Level Integration
Windows Docker Desktop Autostart
On Windows, ensure Docker Desktop itself starts at login:
1# Check Docker Desktop startup configuration (PowerShell)2Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run" -Name "Docker Desktop"3
4# Docker Desktop should have a registry entry pointing to:5# C:\Program Files\Docker\Docker\Docker Desktop.exeTo configure Docker Desktop to start at login:
- Open Docker Desktop Settings
- Navigate to General tab
- Enable "Start Docker Desktop when you log in"
- Click "Apply & Restart"
Windows Service Management
For Docker Engine on Windows Server (not Desktop), manage the service:
1# Check Docker service status2Get-Service docker3
4# Set Docker service to start automatically5Set-Service -Name docker -StartupType Automatic6
7# Start Docker service8Start-Service docker9
10# Verify service configuration11Get-Service docker | Select-Object Name, Status, StartTypeAdvanced Restart Policy Patterns
Health Check Integration
Combine restart policies with health checks for more intelligent restart behavior:
1docker run -d \2 --name smart-web-app \3 --restart=unless-stopped \4 --health-cmd="curl -f http://localhost:8080/health || exit 1" \5 --health-interval=30s \6 --health-timeout=10s \7 --health-retries=3 \8 web-app:latestThis configuration ensures:
- Container restarts automatically unless manually stopped
- Health checks run every 30 seconds
- Container marked unhealthy after 3 consecutive failures
- Monitoring systems can detect unhealthy state even if container is running
Dependency Management
When containers depend on each other, consider startup order:
1# Start database first with unless-stopped2docker run -d \3 --name app-database \4 --restart=unless-stopped \5 postgres:156
7# Start application with dependency awareness8docker run -d \9 --name app-backend \10 --restart=unless-stopped \11 --link app-database:database \12 --health-cmd="pg_isready -h database" \13 --health-interval=10s \14 backend:latestPerformance Considerations
Resource Limits and Restart Policies
When using restart policies, especially always or unless-stopped, consider setting resource limits to prevent runaway containers from consuming all system resources:
1docker run -d \2 --name resource-limited-service \3 --restart=unless-stopped \4 --memory="512m" \5 --memory-swap="1g" \6 --cpus="1.5" \7 --pids-limit=200 \8 service:latestMemory Limits:
--memory: Hard limit on memory usage--memory-swap: Total memory (memory + swap) limit- Container will be killed if it exceeds memory limit, triggering restart policy
CPU Limits:
--cpus: Number of CPU cores available (can be fractional)--cpu-shares: Relative CPU weight (default 1024)
Process Limits:
--pids-limit: Maximum number of processes/threads in container- Prevents fork bombs from affecting host system
Restart Timing and System Load
Understanding Docker's restart timing helps prevent system overload:
1# Restart backoff formula (approximate):2# delay = min(max_delay, initial_delay * 2^(attempt_number))3#4# Attempt 1: 100ms5# Attempt 2: 200ms6# Attempt 3: 400ms7# Attempt 4: 800ms8# Attempt 5: 1600ms9# And so on, up to a maximum interval