Suggest an editImprove this articleRefine the answer for “What is a Docker restart policy and what options exist?”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**A Docker restart policy** tells the daemon when to automatically restart an exited container. Four options: `no` (default), `on-failure[:N]`, `always`, `unless-stopped`. ```bash docker run --restart=unless-stopped myapp # production default docker run --restart=on-failure:5 myjob # try up to 5 times docker run --restart=always mywebservice # always come back docker run myapp # default: no restart ``` **Key:** `unless-stopped` is the production sweet spot — restarts on crash and on host reboot, but respects your manual `docker stop`. `always` ignores manual stop too. `no` is the default, which is wrong for any long-running service.Shown above the full answer for quick recall.Answer (EN)Image**Docker restart policies** automate container resilience. Crash? The daemon restarts you. Host reboot? Container comes back. The four options trade off control vs. automation differently — pick by what you want the container to survive. ## Theory ### TL;DR - `--restart=<policy>` on `docker run` (or `restart: <policy>` in Compose) sets the policy. - **Four values:** `no`, `on-failure[:N]`, `always`, `unless-stopped`. - **Production default: `unless-stopped`** — survives crashes and host reboots, respects manual stop. - **Default if not specified: `no`** — container exits and stays exited. - Restart policies kick in on **container exit**, regardless of whether the exit was clean (0) or not. Filtering by code is what `on-failure` adds. ### The four policies | Policy | On exit (any code) | On exit code 0 | After host reboot | Respects manual stop | |---|---|---|---|---| | `no` (default) | no | no | no | n/a | | `on-failure[:N]` | yes if code != 0, up to N times | no | no (does not survive reboot) | yes | | `always` | yes | yes | yes | **no** (restarts even after stop) | | `unless-stopped` | yes | yes | yes (if was running) | **yes** | #### `no` — the default ```bash docker run myapp # Crashes → exited. Stays exited. # Host reboots → container does not come back. ``` Fine for one-off commands (`docker run --rm` for a CI job). Wrong for any service you expect to keep running. #### `on-failure[:N]` — restart on crash, up to N times ```bash docker run --restart=on-failure myjob # unlimited retries, on non-zero exit docker run --restart=on-failure:5 myjob # max 5 retries ``` Use for **batch jobs** that should retry on transient failure but eventually give up. The host-reboot does not bring them back (they are jobs, not services). #### `always` — restart no matter what ```bash docker run --restart=always mysvc # Crash, clean exit, host reboot → daemon brings it back every time. # Even after `docker stop`, the daemon restarts it. ``` The naming is literal: ALWAYS. Including after you stop it manually — to actually stop, you have to `docker rm` it. Surprising; usually you want `unless-stopped` instead. #### `unless-stopped` — the production default ```bash docker run --restart=unless-stopped mysvc # Crash → restart. Host reboot → restart. Manual `docker stop` → STAYS stopped. ``` The right policy for 95% of long-running services. Daemon restarts on failure or reboot; it respects your intent when you stop manually. ### How it interacts with the daemon - **On container exit:** the daemon checks the policy and decides whether to restart. - **On daemon restart (`systemctl restart docker`):** containers with `always` and `unless-stopped` (that were running before the daemon restart) come back. `on-failure` does NOT — it is per-exit only. - **On host reboot:** same as daemon restart. - The daemon uses **exponential backoff** between retries: 100ms, 200ms, 400ms, ... up to a cap. Prevents hot-loop crash storms. ### Compose syntax ```yaml services: api: image: myapp restart: unless-stopped # most common worker: image: myworker restart: on-failure # job-style oneoff: image: alpine command: echo hi restart: "no" # one-shot ``` Note: `"no"` in YAML must be quoted, otherwise YAML parses it as boolean `false`. ### Common mistakes **Forgetting to set a policy on a long-running service** ```bash # WRONG: defaults to "no"; container does not survive a host reboot docker run -d --name api -p 80:80 myapp # RIGHT docker run -d --name api -p 80:80 --restart=unless-stopped myapp ``` This is the most common operations mistake on single-host deploys. The container works, you go home, the host reboots overnight, the service is down and your phone lights up. **Using `always` and being surprised manual stop does not stick** ```bash $ docker run -d --name api --restart=always myapp $ docker stop api $ docker ps # api is back ``` `always` literally means always. Use `unless-stopped` if you want manual stop to be respected. **Crash-loop without exit-code filter** ```bash # Container exits with code 0 but you want restart only on failure docker run --restart=always myjob # Restarts forever, even on clean exits. Probably not what you want. # Better: docker run --restart=on-failure myjob ``` **Forgetting that `on-failure` does not survive reboot** If the container is paused or running when you reboot, on-failure does not bring it back. Use `unless-stopped` if you need reboot survival. ### Restart policy + healthcheck Docker's restart policy reacts to **process exit**, not to **healthcheck unhealthy**. An unhealthy container that has not exited is not restarted by Docker. To act on healthcheck: - Swarm replaces unhealthy tasks with new ones (configurable). - Compose with the `condition: service_healthy` only gates startup, not runtime restart. - Plain Docker: an external watchdog (autoheal container, custom script) can `docker restart` based on health status. ```bash # willfarrell/autoheal: monitors and auto-restarts unhealthy containers docker run -d \ --name autoheal \ -v /var/run/docker.sock:/var/run/docker.sock \ -e AUTOHEAL_CONTAINER_LABEL=autoheal \ willfarrell/autoheal docker run -d --label=autoheal=true --health-cmd="..." myapp ``` ### Real-world usage - **Production single-host services:** `unless-stopped` everywhere, almost without exception. - **CI / build containers:** no restart policy (default `no`). They run, exit, and stay exited. - **Background workers:** `on-failure:N` so transient crashes retry but a permanently-broken job eventually gives up. - **Critical infrastructure (the host itself depends on it):** sometimes `always` is justified — e.g., a security agent that must be up no matter what. ### Follow-up questions **Q:** What is the difference between `always` and `unless-stopped`? **A:** `always` restarts even after manual `docker stop`. `unless-stopped` does not. Both survive crashes and host reboots; the difference is whether your intent (`docker stop`) is respected. **Q:** Does the restart policy apply if I `docker rm` the container? **A:** No — once removed, there is no container to restart. Policies operate on existing containers. **Q:** How can I see which policy a container has? **A:** `docker inspect <name> --format '{{.HostConfig.RestartPolicy.Name}}'`. Returns `always`, `unless-stopped`, `on-failure`, or empty for `no`. **Q:** Does `--restart` apply when the container is in a Swarm service? **A:** No. Swarm services use `restart_policy:` in the deploy config (with `condition: any|on-failure|none`, `delay`, `max_attempts`). The `--restart` flag is for standalone containers. **Q:** (Senior) When should you NOT use a restart policy at all? **A:** When something else is responsible for the container's lifecycle. K8s pods are managed by the kubelet — Docker restart policy is irrelevant inside a K8s pod (and ignored). Same for systemd-managed containers via `docker run --rm` from a unit. The rule: one restart authority per container; pick the orchestration layer that should own it. ## Examples ### Production-style service with multiple resilience layers ```bash $ docker run -d \ --name api \ --restart=unless-stopped \ -p 3000:3000 \ -v api_data:/data \ --health-cmd='curl -f http://localhost:3000/health || exit 1' \ --health-interval=30s \ --memory=512m \ myapp:1.0 ``` - Process crash → daemon restarts via policy. - Host reboot → container comes back. - Manual `docker stop` → stays stopped (you know what you did). - Healthcheck makes status visible to monitoring + reverse proxies. ### Compose: different policies per service ```yaml services: api: image: myapp restart: unless-stopped worker: image: myworker restart: on-failure # batch retries migrator: image: mymigrator restart: "no" # one-shot, do not restart profiles: [migrate] # opt-in profile ``` Different shapes of work, different policies. The migrator should run once and stay exited. ### Capping retries to prevent infinite loops ```bash $ docker run -d --name flaky --restart=on-failure:3 myjob # After 3 non-zero exits, the daemon stops trying. $ docker ps -a --filter name=flaky --format '{{.Status}}' Exited (1) 5 seconds ago # final state, no more retries ``` `on-failure:N` is the safety net for jobs that might fail forever. Without the cap, the daemon retries indefinitely.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.