Docker & DevOps

Docker restart policies: keep containers running after a reboot

How Docker's restart policies work, what no, on-failure, always and unless-stopped do after a crash or VPS reboot, and how to change the policy on a container that is already running.

BeginnerLinux server5 min read

A container without a restart policy stays down after it crashes or after you reboot the VPS. A restart policy tells the Docker daemon to bring it back for you. This guide explains the four policies, how they behave in practice, and how to set or change them without recreating your containers.

Before you start

  • A Linux VPS with Docker Engine and the Compose plugin. See Install Docker and Docker Compose if you still need them.
  • At least one container you want to keep running.
  • A user that can run docker commands.

The four restart policies

  • no (the default): Docker never restarts the container on its own.
  • on-failure[:max-retries]: restart only when the main process exits with a non-zero code, which usually means a crash. You can cap the number of attempts, for example on-failure:5.
  • always: restart whenever the container stops, for any reason. If you stop it by hand, it stays stopped until the Docker daemon restarts, and then it starts again.
  • unless-stopped: like always, except a container you stopped by hand stays stopped after a daemon restart or reboot.

For most web apps, databases and background services on a VPS, unless-stopped is the right choice. It recovers from crashes and reboots, but it respects your decision when you stop something on purpose.

How the policies behave after a reboot

When the VPS boots, systemd starts the Docker service. The daemon then looks at every container and starts the ones whose policy says they should run:

  • always: started, even if you had stopped it before the reboot.
  • unless-stopped: started only if it was running when the server went down.
  • on-failure: not started after a clean reboot, because the container did not fail. Use it for jobs that should only retry on errors.
  • no: not started.

All of this depends on Docker itself starting at boot. On most installs it does. Confirm it:

Bash
systemctl is-enabled docker

If the output is disabled, enable it:

Bash
sudo systemctl enable docker

Note: Docker waits about ten seconds of uptime before it treats a restart as successful. A container that crashes again within that window gets an increasing delay between attempts, starting at 100 ms and doubling each time, so a broken container does not hammer the CPU.

Set a policy with docker run

Add --restart when you create the container:

Bash
docker run -d --name web --restart unless-stopped -p 8080:80 nginx:stable

For a retry limit:

Bash
docker run -d --name worker --restart on-failure:5 myworker:1.0

Set a policy in Docker Compose

In compose.yaml, use the restart key on each service:

YAML
services:
  app:
    image: myapp:1.0
    restart: unless-stopped
  db:
    image: postgres:16
    restart: unless-stopped

Apply the change:

Bash
docker compose up -d

Compose recreates any service whose configuration changed.

Tip: Quote "no" in YAML (restart: "no"). Without quotes, YAML can read no as the boolean false.

Change the policy on a running container

You do not need to recreate a container to change its policy. docker update changes it in place:

Bash
docker update --restart unless-stopped web

To apply the same policy to every running container at once:

Bash
docker update --restart unless-stopped $(docker ps -q)

If the container is managed by Compose, also change the restart key in the file. Otherwise the next docker compose up -d puts the old value back.

Restart policies are not health checks

A restart policy only reacts when the main process exits. If the app hangs but the process keeps running, Docker sees nothing wrong and does nothing. A container marked unhealthy by a health check is also not restarted by plain Docker Engine.

To catch hangs, add a health check and make your app exit when it fails, or use an external monitor. Add health checks to Docker containers explains the options.

Check it works

See the policy each container has:

Bash
docker inspect --format '{{.Name}} {{.HostConfig.RestartPolicy.Name}}' $(docker ps -aq)

Then test a crash. Kill the main process and watch Docker restart it:

Bash
docker kill web
docker ps --filter name=web

Warning: docker kill counts as a manual stop, so unless-stopped and always will not restart it until the daemon restarts. To simulate a real crash, run docker exec web kill 1 instead, then check docker ps again after a few seconds.

The best test is a planned reboot during a quiet period:

Bash
sudo reboot

After you reconnect, docker ps should list every container with unless-stopped or always as Up.

Troubleshooting

  • Containers do not start after a reboot: the Docker service is not enabled, or the containers have policy no. Check with systemctl is-enabled docker and the inspect command above.
  • Container shows Restarting (1) forever: the app crashes on start. Read docker logs --tail 50 <name> and fix the cause. Fix a Docker container that exits immediately lists the usual reasons.
  • A container you stopped came back: it has policy always. Switch it to unless-stopped with docker update.
  • Policy reverted after a deploy: the Compose file still has the old restart value. Update the file, not just the container.

Next steps

Was this guide helpful?

Still stuck?

Ask MdmHost AI for a quick answer, or open a ticket and our team will take a look. We are here 24/7.