Skip to content

Docker Restart Policies Explained: no, always, unless-stopped, on-failure

What no, always, unless-stopped, and on-failure actually do in Docker. How each handles crashes, reboots, and manual stops, plus the gotchas that catch people.

SDSysadmin Desk September 12, 2026 7 min read
Comparison chart of the four Docker restart policies showing how each reacts to a crash, a reboot, and a manual stop

A restart policy is one line, and it decides whether your container comes back on its own after a crash, a reboot, or a manual stop. Get it right and your services survive a server restart without you touching them. Get it wrong and you either lose a service after every reboot or fight a container that refuses to stay down.

Docker has four restart policies: no, always, unless-stopped, and on-failure. They sound self-explanatory, but the differences between always and unless-stopped — and how each one reacts when the Docker daemon itself restarts — are where people get caught.

This guide explains exactly what each policy does in three situations that matter: the process crashes, the host reboots, and you stop the container by hand.

The four policies at a glance

# Set on docker run
docker run -d --restart=unless-stopped --name web nginx:1.27

# Or in a Compose file
#   restart: unless-stopped

Here’s how each policy behaves in the three scenarios that actually come up:

What each policy does in three situations

Policy Process crashes
no (default) Stays stopped
on-failure Restarts (if exit ≠ 0)
always Restarts
unless-stopped Restarts

Read the bottom two rows carefully — that one column on the right is the whole difference between always and unless-stopped.

no — the default that does nothing

no is the default policy. If you don’t pass --restart, this is what you get. The container runs until the process exits or you stop it, and then it stays stopped. No automatic recovery from anything.

docker run -d --name once alpine sleep 30
# After 30 seconds the process exits and the container stays stopped.

This is the right choice for one-off tasks, short scripts, and anything you run interactively and don’t want resurrected. It’s the wrong choice for a web server or database you expect to keep running, because a single crash or a reboot takes it down for good.

on-failure — retry only when something broke

on-failure restarts the container only when it exits with a non-zero exit code, which is how a process signals an error. A clean exit (code 0) is treated as success and the container stays stopped.

docker run -d --restart=on-failure:5 --name worker my-batch-job

That :5 is a retry cap. Docker will restart the container up to five times; after the fifth failure it gives up and leaves it stopped. Without the cap, a job that fails instantly on every start would loop forever, which is rarely what you want for a batch process.

on-failure fits jobs and workers: a task that should retry a few times if it errors, but shouldn’t restart endlessly and shouldn’t relaunch after finishing normally. It’s a poor fit for a service that exits 0 on a crash or one you always want running regardless of exit code.

always — bring it back no matter what

always restarts the container whenever it stops, with one important twist around manual stops.

If the process crashes, it restarts. If the host or the Docker daemon restarts, the container starts again. And if you stop it yourself with docker stop, it stays stopped for now — but the next time the Docker daemon starts, it comes back anyway.

docker run -d --restart=always --name proxy nginx:1.27

That last part is the gotcha. You stop a container on purpose, reboot the box for maintenance, and the container you deliberately stopped is suddenly running again. always doesn’t remember that you wanted it down — it only knows it should be running whenever the daemon is up.

Use always when you genuinely want a container running at all times and a manual stop should only ever be temporary. For most services, that’s stronger than you want, which is why the next policy usually wins.

unless-stopped — the sensible default

unless-stopped behaves like always in every case except one: it remembers a manual stop. If you stop the container yourself, it stays stopped — across daemon restarts and host reboots — until you start it again.

docker run -d --restart=unless-stopped --name web nginx:1.27

Walk through the scenarios:

  • Process crashes → Docker restarts it.
  • Host reboots while the container was running → it starts back up.
  • You run docker stop web → it stays down, and a reboot won’t bring it back.
  • You run docker start web again → it’s back under the policy.

That behavior matches how people actually think. “Keep this running, but if I stop it, I meant it.” For nearly every long-running service — web servers, databases, reverse proxies — this is the policy to reach for.

Setting and changing policies

In a Compose file, the policy is a single line per service:

services:
  web:
    image: nginx:1.27
    restart: unless-stopped
  worker:
    image: my-batch-job
    restart: on-failure

Note that Compose uses restart: without the -- prefix, and on-failure with a retry cap isn’t expressed here the same way as on the CLI — for capped retries in Compose, use the long-form deploy.restart_policy. For the simple cases above, the short form is all you need.

To change the policy on a container that’s already running, you don’t have to recreate it:

# Change policy in place on a running container
docker update --restart=unless-stopped web

# Confirm what policy a container currently has
docker inspect -f '{{ .HostConfig.RestartPolicy.Name }}' web

Choosing a restart policy

  • Long-running service you sometimes stop for maintenance → unless-stopped
  • Container that must always run, even after a manual stop → always
  • Batch job or worker that should retry on error → on-failure (add a retry cap)
  • One-off task or interactive run you don't want resurrected → no
  • Confirm the policy with docker inspect after setting it

When the policy isn’t the problem

A restart policy does exactly what it’s told, which is why a container stuck in a restart loop is usually not a policy bug. With always or unless-stopped, a container that crashes the instant it starts will be relaunched again and again — the policy keeps doing its job while the container keeps failing.

When that happens, don’t change the policy first. Read the logs and find out why the container exits:

docker logs --tail 50 web
docker compose logs --tail 50 web

The real cause is almost always a bad config value, a missing mounted file, a port conflict, or a dependency that isn’t ready. Fix that and the loop stops. There’s a full diagnostic walkthrough in fixing a container that keeps restarting, and if the daemon itself isn’t reachable, start with fixing cannot connect to the Docker daemon.

For most stacks, set unless-stopped on your services and move on. It survives the reboots and crashes you care about, respects the stops you make on purpose, and stays out of your way the rest of the time.

Frequently asked questions

What's the difference between always and unless-stopped?

Both restart a container after a crash and after the Docker daemon or host restarts. The difference shows up when you stop a container manually. With always, the container comes back the next time the daemon starts. With unless-stopped, a manual stop is respected and the container stays down until you start it yourself.

Which restart policy should I use for a normal service?

unless-stopped is the safe default for long-running services. It survives crashes and reboots but won't override a deliberate stop, so maintenance is predictable. Use always only when you want a container to come back even after you stopped it, and on-failure for jobs that should retry only when they exit with an error.

Does on-failure restart a container that exits cleanly?

No. on-failure only restarts when the container exits with a non-zero code. If the process exits 0, Docker treats that as success and leaves it stopped. You can cap retries with on-failure:5 so a permanently broken container stops looping.

Why does my container keep restarting in a loop?

A restart policy of always or unless-stopped will keep relaunching a container that crashes immediately on start, usually from a bad config, a missing file, or a failed dependency. The policy is doing its job; the container is the problem. Check docker logs to find the real error before changing the policy.

Can I change a restart policy without recreating the container?

Yes. Run docker update --restart=unless-stopped to change the policy on a running container in place. With Compose, edit the restart: line and run docker compose up -d to apply it.

Sources & further reading

Official vendor documentation referenced while writing this guide.

SD

Sysadmin Desk

Infrastructure & Cloud

Hands-on guidance for infrastructure, virtualization, and containers — Hyper-V, VMware, Docker, and the day-to-day operations work that keeps environments running.

MCSA Guru provides independent, educational IT guidance. Microsoft, Windows, Windows Server, Microsoft 365, Exchange, and Microsoft Teams are trademarks of Microsoft Corporation; Docker is a trademark of Docker, Inc. MCSA Guru is not affiliated with or endorsed by Microsoft or Docker. Always test changes in a safe environment before applying them in production.

Related guides

Fixing something right now?

Jump straight into the guide library or search for the exact error or task you are dealing with.