E-NO
Docker Restart Policies configuration 10 Min Read

Docker Restart Policies: Configuration Mistakes and How to Avoid Them

calendar_today Published: 2026-09-21
update Last Updated: 2026-09-21
analytics SEO Efficiency: 100%
Technical guide illustration for Docker Restart Policies: Configuration Mistakes and How to Avoid Them.

Intro

Docker restart policies are a core piece of container reliability, but they are also a common source of confusion. Setting the wrong policy can leave a production service down after a reboot, mask application bugs by restarting a failing container indefinitely, or cause a container to restart at the worst possible moment during maintenance. This guide explains how Docker restart policies actually work, walks through common configuration mistakes with concrete examples, and shows you how to validate, roll back, and troubleshoot restart behavior safely.

We'll cover the four policy types, what happens in different failure scenarios (daemon restarts, manual stops, exit codes), and how to choose correctly. You'll see real commands and expected output for inspecting and changing policies, plus a practical testing workflow you can run locally before deploying to production.

Version and Environment Inventory

Before changing any restart policy, confirm your environment and capture the current state. This prevents making changes to the wrong container or assuming behavior from a different Docker version.

Check your Docker version and runtime

Restart policies have been stable for years, but syntax and defaults can vary slightly across Docker Engine, Docker Desktop, and rootless installations. Run:

docker version --format '{{.Server.Version}}'

Expected output example:

24.0.7

Also check the container runtime (e.g., containerd) and storage driver if you are troubleshooting filesystem persistence after restarts:

docker info --format '{{.Driver}} {{.CgroupVersion}}'

Capture current restart policies

List all containers and their restart policies using a custom format:

docker ps -a --format 'table {{.Names}}\t{{.Status}}\t{{.Label "com.docker.compose.project"}}'

To see the exact restart policy of a specific container, use docker inspect:

docker inspect --format '{{.HostConfig.RestartPolicy.Name}} (max retries: {{.HostConfig.RestartPolicy.MaximumRetryCount}})' my-app

Example output:

always (max retries: 0)

For Compose projects, the policy is defined in docker-compose.yml under the restart: key. View all services and their current container state with:

docker compose ps

Confirm data persistence before restart tests

If your container writes stateful data, verify that the data lives in a volume or bind mount, not in the container's writable layer. Otherwise, a restart may lose data.

Inspect mounts for a running container:

docker inspect --format '{{range .Mounts}}{{.Type}} {{.Source}} -> {{.Destination}}{{"\n"}}{{end}}' my-app

Example output:

volume app_data -> /var/lib/app

If you see no mounts and the application writes to /var/lib/app inside the container, that data will be lost when the container is removed (but not when it merely restarts). Always design stateful containers to use volumes or bind mounts.

Understanding Restart Policies

Docker provides four restart policy values:

PolicyBehavior when container exitsBehavior on daemon restartTypical use case
noNever restart automaticallyNever restartedOne-off jobs, debugging
on-failureRestart only if exit code != 0, up to max retriesRestarted only if last exit was failureServices that should stop on repeated failure
alwaysAlways restart regardless of exit codeAlways restarted, even if manually stopped before daemon restartCore production services (web, API)
unless-stoppedAlways restart unless the container was manually stopped by userRestarted unless user had stopped it before daemon restartMost production services; safer than always

Key differences:

  • always will restart a container even if you manually stopped it before the Docker daemon restarts. This can surprise you during maintenance windows.
  • unless-stopped remembers that you manually stopped the container and will not restart it after a daemon restart. It is the recommended choice for most production workloads.
  • on-failure allows a maximum retry count. Once exceeded, the container stops. This helps avoid infinite restart loops for broken applications.

What triggers a restart?

A restart policy kicks in when the container's main process exits. Docker does not restart a container that is running but unhealthy (unless you use a health check with autoheal, which is separate). The restart policy also does not apply if the container is removed or if the daemon is stopped while the container is still running (the container is stopped normally and then restarted according to policy when daemon starts).

Default policies

  • docker run without --restart defaults to no.
  • Docker Compose defaults to no (unless overridden).
  • Some orchestrators (e.g., Kubernetes) handle restarts themselves; this article focuses on plain Docker and Compose.

Quick check 1 of 2

According to Docker's restart policy details, how long must a container be running before its restart policy takes effect?

From the reference: 'A restart policy only takes effect after a container starts successfully. In this case, starting successfully means that the container is up for at least 10 seconds and Docker has started monitoring it.'

Safe Configuration Path

Now that you understand the policies, follow a controlled process to change one.

Step 1: Identify the target and current policy

Choose a single container and record its current policy using docker inspect as shown earlier. For Compose, note the service name and the project directory.

Step 2: Choose the new policy with justification

Ask:

  • Is this a long-running service that should always be up? Use unless-stopped (preferred) or always.
  • Is it a batch job or a short-lived worker? Use no or on-failure with a small retry count.
  • Do I need to cap restart attempts to avoid crash loops? Use on-failure:5 (retry 5 times, then stop).

Example: a web server should restart unless an operator deliberately stopped it for maintenance. So:

services:
  web:
    image: nginx:1.25
    restart: unless-stopped

Step 3: Apply the change

For a running container, you cannot change the restart policy via docker update. Actually, docker update does support --restart since Docker 1.11. So you can update a running container without recreating:

docker update --restart unless-stopped my-app

For a container created with docker run, specify the policy at creation:

docker run -d --name my-app --restart unless-stopped nginx:1.25

For Compose, edit docker-compose.yml and run:

docker compose up -d

This recreates the service with the new policy if the configuration changed.

Step 4: Verify the new policy

Immediately check that the policy is set correctly:

docker inspect --format '{{.HostConfig.RestartPolicy.Name}}' my-app

Expected output: unless-stopped.

Step 5: Run a controlled restart test

Do not just trust the setting; simulate the failure condition. For unless-stopped, stop the container manually and confirm it does not restart on its own:

docker stop my-app
sleep 5
docker ps -a --filter name=my-app --format '{{.Status}}'

Expected output shows the container as Exited (0) and not running. That is correct for a manual stop with unless-stopped. To test automatic restart on failure, kill the main process with a nonzero exit code:

docker kill --signal=SIGKILL my-app
sleep 2
docker ps --filter name=my-app --format '{{.Status}}'

You should see the container Restarting or Up (with a new start time).

Rollback plan

If the new policy causes unexpected behavior (e.g., a restart loop), revert to the previous policy immediately:

  • For docker run containers, use docker update --restart <old-policy> my-app.
  • For Compose, change restart: in the YAML and run docker compose up -d again.
  • If the container is stuck in a restart loop, you may need to stop it first: docker stop my-app (this works even with restart policy unless it's always and the daemon restarts? Actually stopping a container overrides restart policy until daemon restart for always; for unless-stopped it persists).

Verification and Diagnostics

After changing a restart policy, verify both the configuration and the actual behavior under failure.

Inspect restart count and last exit

Use docker inspect to see how many times the container has restarted:

docker inspect --format '{{.RestartCount}}' my-app

If the count is climbing rapidly, the container is crash-looping. Investigate the exit code:

docker inspect --format '{{.State.ExitCode}}' my-app

Exit code 0 means clean exit; nonzero indicates error. For on-failure, a high retry count may exhaust the maximum and stop the container permanently.

Check logs for the cause of failure

docker logs my-app --tail 100

Look for stack traces, missing files, or port conflicts. If the application needs a health check, combine restart policy with a Docker healthcheck to avoid restarting a container that is running but unhealthy:

HEALTHCHECK --interval=30s --timeout=5s --retries=3 CMD curl -f http://localhost/ || exit 1

Then use unless-stopped so Docker restarts only on process failure, not on health check failure (unless you use an orchestrator feature).

Test daemon restart behavior

A common mistake is assuming a container with always will start after a host reboot. Always test by restarting the Docker daemon or the host in a staging environment.

On a Linux server with systemd:

sudo systemctl restart docker
sleep 10
docker ps --filter name=my-app

If the container does not appear, check docker ps -a to see if it is stopped. For unless-stopped, if you had manually stopped it before the daemon restart, it will remain stopped. That is expected.

Failure Modes and Recovery

Several failure modes arise from restart policy misconfiguration. Here are common ones and how to recover.

1. Setting always when unless-stopped is intended

Symptom: You stop a container for maintenance, reboot the server, and the container starts again unexpectedly. This can cause split-brain or resource contention if the service should remain down.

Why: always ignores manual stops across daemon restarts. Docker assumes you want the container running no matter what.

Recovery: Change policy to unless-stopped:

docker update --restart unless-stopped my-app

Then if you need it stopped, stop it before reboot; it will stay stopped.

2. Using on-failure without a limit on a broken app

Symptom: Container constantly restarts, exhausting CPU and filling logs.

Why: on-failure without MaximumRetryCount (or on-failure:0) means unlimited retries. The app may exit with code 1 repeatedly.

Recovery: Set a finite retry count, e.g., 5:

docker update --restart on-failure:5 my-app

Then diagnose the root cause by checking logs while the container is stopped.

3. Forgetting to set a restart policy at all

Symptom: After a host reboot, your service is down.

Why: Default policy is no. The container never restarts automatically.

Recovery: Add --restart unless-stopped (or always) to docker run, or restart: unless-stopped in Compose. Recreate the container.

4. Applying a restart policy to a one-off job

Symptom: A data migration or batch job runs repeatedly after completion because the container exits with code 0 and the policy is always or unless-stopped.

Why: These policies restart regardless of exit code. A job that finishes successfully should not be restarted.

Recovery: Use --restart no or on-failure with retries for jobs. If already running, stop and remove the container, then run a new one with the correct policy.

5. Misunderstanding on-failure and exit code 0

Symptom: You expect on-failure to restart when the app crashes, but it does not restart when the app exits with code 0 after a fatal error (some apps exit 0 even on failure).

Why: on-failure only triggers on nonzero exit codes. If the app interprets a crash as a clean shutdown (exit 0), Docker will not restart it.

Recovery: Fix the application to exit nonzero on fatal errors, or use a wrapper script that maps errors to exit 1. Then use on-failure or unless-stopped.

6. Restart policy conflicts with Compose depends_on

Symptom: In Compose, service A (with restart: always) restarts continuously, causing service B (which depends on A) to also restart because depends_on makes B recreate when A restarts. This creates a cascade.

Why: Compose's default depends_on condition is service_started, not service_healthy. If A crashes, B may start fine but A restarts, and Compose may restart both.

Recovery: Use depends_on with condition: service_healthy and define healthchecks. Limit restart policy on A to on-failure with a finite retry count to prevent infinite loops.

7. Losing data because of volume misconfiguration

Symptom: Container restarts fine but data is missing after a restart (e.g., database files gone).

Why: The data was written to the container's writable layer instead of a volume. A simple restart preserves the writable layer, but if the container is recreated (e.g., by Compose up after a policy change), all data is lost.

Recovery: Redesign with a volume or bind mount. If data is critical, recover from backups. Test persistence by recreating the container deliberately before production.

Quick check 2 of 2

Which flag is used to configure a restart policy for a container when using docker run?

The reference states: 'To configure the restart policy for a container, use the --restart flag when using the docker run command.'

Operations Checklist

Use this checklist before and after modifying restart policies in production. Assign a single owner for the change and a review date.

  • [ ] Owner: Priya Shah, Engineering Lead. Review date: after every change and quarterly audit.
  • [ ] Confirm Docker version and runtime are known (docker version, docker info).
  • [ ] Capture current restart policy of target container: docker inspect --format '{{.HostConfig.RestartPolicy.Name}}' <container>.
  • [ ] Check if container has volumes or bind mounts and that data is persisted outside the container.
  • [ ] Choose new policy with documented justification. Example: change no to unless-stopped for web service because it must survive host reboots unless deliberately stopped.
  • [ ] Apply change via docker update --restart or Compose file edit + docker compose up -d.
  • [ ] Verify new policy with docker inspect.
  • [ ] Run controlled restart tests:
  • Manual stop: container should remain stopped for unless-stopped; should restart for always only after daemon restart? Actually, manual stop overrides always until daemon restart. Test daemon restart separately.
  • Simulate failure: docker kill the main process and confirm restart.
  • Check restart count: docker inspect --format '{{.RestartCount}}' should increment.
  • [ ] Check logs for error messages: docker logs --tail 100.
  • [ ] Confirm rollback path: know how to revert policy quickly.
  • [ ] Document the change in the runbook with timestamp and owner.
  • [ ] Schedule a quarterly review of all container restart policies to ensure they still match service requirements.

Common Pitfalls and How to Avoid Them

Beyond the failure modes above, these pitfalls occur frequently:

  1. Assuming always is safer than unless-stopped. In reality, always can cause containers to start after a reboot even when you intended to keep them down for maintenance. Use unless-stopped for most services.
  1. Not testing daemon restart behavior. Many developers only test killing the container process, not rebooting the Docker daemon. Always test both in a staging environment.
  1. Ignoring exit codes. An application that exits 0 on fatal error defeats on-failure. Ensure your app follows Unix conventions: nonzero for errors.
  1. Using on-failure with too many retries. If the app fails permanently, a high retry count delays detection. Use a low number (3-5) and monitor logs.
  1. Changing policy without checking data persistence. If you recreate a container to apply a policy change (e.g., Compose up recreates), data in the container's writable layer is lost. Always use volumes for stateful services.
  1. Not documenting the policy choice. Teams may not know why a policy was set, leading to accidental changes. Add comments in Compose files:
services:
  db:
    image: postgres:16
    restart: unless-stopped  # stay up unless manually stopped for maintenance

Conclusion

Docker restart policies are simple in concept but easy to get wrong in production. By understanding the exact behavior of no, on-failure, always, and unless-stopped, and by following a careful change process with verification and rollback, you can ensure your containers are available when they should be and down when you need them down.

Start with a low-risk container in a staging environment. Capture its current policy, apply a change, run the restart tests described here, and document the results. Then extend the process to production. Regularly audit your restart policies as part of operational hygiene, and you will avoid the most common pitfalls that lead to unexpected downtime or uncontrolled restarts.

Related Research

Article Quality Score

Reader usefulness 100%
  • check_circle Reader-ready guide
  • check_circle Practical examples included
  • check_circle Clean SEO article URL