Why a Docker container keeps restarting, and how to find the cause
A container keeps restarting because its main process exits and the restart policy starts it again. Docker waits a little longer before each try, so the loop can run for hours without anyone noticing. The exit code usually tells you which cause you have.
Run docker ps -a to see the status, docker inspect for the exit code and restart count, and docker logs for the last lines before the exit.
Confirm the loop
docker ps -a --filter name=myapp
docker inspect -f '{{.RestartCount}} {{.State.ExitCode}} {{.State.OOMKilled}}' myapp
docker logs --tail 100 myappA status of Restarting (1) 5 seconds ago and a growing RestartCount mean the container is looping. OOMKilled set to true means the kernel killed it for memory.
Read the exit code
| Exit code | Meaning | Usual cause |
|---|---|---|
| 0 | The process finished | A one-off task under restart: always, or an app that went to the background so the shell exited |
| 1 | Application error | A missing env var, bad config, a failed migration or a crash on boot |
| 126 / 127 | Command not runnable / not found | A wrong CMD or entrypoint, a missing binary, a script without execute permission or with Windows line endings |
| 137 | Killed (SIGKILL) | Out of memory, or a stop that ran past its grace period |
| 139 | Segmentation fault | A bug in a native module, or a library built for another libc (musl or glibc) |
| 143 | Terminated (SIGTERM) | A stop that the app handled, or a liveness probe that failed on Kubernetes |
Exit code 137 has its own guide: exit code 137 and OOM killed.
Fix the common causes
- A crash on start. The last log lines show the error. Start the image with a shell (
docker run -it --entrypoint sh myimage) and run the command by hand. - Out of memory. Compare memory use with the container’s limit. Raise the limit, or look for a leak if memory climbs steadily before each restart.
- The wrong port or address. The app starts but listens on
127.0.0.1instead of0.0.0.0, or on another port. Docker itself keeps such a container running, but a platform health check or a Kubernetes liveness probe fails and restarts it. - A dependency that is not ready. The app exits when the database is not up yet. Retry the connection in the app, or use
depends_onwithcondition: service_healthyin Compose. - The wrong restart policy. A container that is meant to finish should not run under
alwaysorunless-stopped.
Docker restart policies
| Policy | Restarts the container when |
|---|---|
no | Never. This is the default. |
on-failure[:N] | It exits with a code other than 0, up to N times |
always | It exits for any reason, and when the Docker daemon starts |
unless-stopped | Like always, except after you stopped it yourself |
Docker doubles the wait between restarts, starting at 100 milliseconds. The wait goes back to 100 milliseconds once the container stays up for 10 seconds.
Kubernetes: “Back-off restarting failed container”
This is the Kubernetes event behind the CrashLoopBackOff status. The pod’s container keeps exiting, and Kubernetes waits longer before each restart, up to five minutes. The causes are the same as above.
kubectl describe pod <pod>
kubectl logs <pod> --previousdescribe shows the last exit code and its reason, such as OOMKilled or Error. logs --previous shows the logs of the run that crashed, not the one that just started.
On an app platform or self-hosted PaaS
App platforms restart a crashed service the same way, each with its own limits and its own place to look. Each platform has its own guide: Railway service keeps restarting, Render service keeps restarting and Fly.io Machine keeps restarting.
On Coolify, the application’s Logs show the error before each exit, and Sentinel’s memory chart shows an out-of-memory climb. Coolify stops the resource once it reaches its restart limit. It notifies on status changes and on the restart limit, but keeps no history of restarts next to memory.
On Dokploy, containers follow the Docker restart policy. Dokploy alerts on CPU and memory for the whole server, but not when a container restarts.