Last week I had to reboot a physical Red Hat 8 Linux server to finish applying security patches. The update included a new kernel, so a reboot was required to boot into it. This is a DEV server running Docker Engine with several containers, and I expected everything to come back up on its own.
It didn’t. After the server came back, the containers were stopped. I had to start them manually, one by one, and only later understood the reason: they were never configured to start automatically when the Docker daemon starts.
This article shows how to check whether your containers are set to start on boot, and how to configure them so you never hit this again.
The root cause: Docker restart policies
Docker does not start containers automatically unless you tell it to. Whether a container comes back after a reboot is controlled by its restart policy – a setting attached to each container.
The restart policy has four possible values:
no— the container is never restarted automatically. This is the default.on-failure— restarts only if the container exits with a non-zero code (that is, it crashed).always— always restarts, including when the Docker daemon starts.unless-stopped— restarts when the daemon starts, unless you had manually stopped the container before.
For a server that needs its containers up after a reboot, unless-stopped is usually the right choice. It starts the container on boot, but respects a manual docker stop – so a container you stopped on purpose stays stopped.
Step 1 — Make sure the Docker daemon itself starts on boot
Before anything else, the Docker service must be enabled. On RHEL/CentOS (systemd), check and enable it wether necessary:
systemctl is-enabled docker
systemctl enable docker
If the daemon itself is not enabled, containers will never come up after a reboot, regardless of their restart policy. (If you don’t have Docker installed yet, see Installing Docker Engine on CentOS.)
Step 2 — Check the current restart policy of a container
To see what a single container is configured to do, run:
docker inspect <container-name> --format '{{.HostConfig.RestartPolicy.Name}}'
If the output is no, that explains why the container didn’t come back automatically – it has the default policy and Docker will not start it.
To check the restart policy of all containers at once (running and not running containers):
for c in $(docker ps -aq); do docker inspect $c --format '{{.Name}} => {{.HostConfig.RestartPolicy.Name}}'; done
Step 3 — Set the restart policy
There are two ways, depending on whether the container already exists.
For a container that already exists, use docker update:
docker update --restart unless-stopped <container-name>
Note: replace <container-name> to your container name. Example: webserver.
For a new container, add --restart at creation time:
docker run -d --name my-app --restart unless-stopped my-image
Notes:
- Replace “my-app” to your container name.
- And replace “my-image” to your Docker image – A container is created based on a Docker Image.
If you use Docker Compose, set it in the docker-compose.yml instead:
services:
my-app:
image: my-image
restart: unless-stopped
Then apply it with docker compose up -d. (If you want to know more about Docker Compose, see Installing Docker Compose on CentOS).
always vs unless-stopped: why it matters
This is the detail that confuses people. Both always and unless-stopped start the container when the Docker daemon starts. The difference is what happens when you manually stop a container:
- With
always, if you rundocker stop my-appand then reboot the server, Docker startsmy-appagain – even though you stopped it on purpose. On a DEV server where you often stop containers manually to test something, this can be annoying. - With
unless-stopped, a manually stopped container stays stopped after a reboot. It only auto-starts if it was running when the daemon stopped.
For most cases – and for my DEV server – unless-stopped is the better default. The full list of policies is documented in the Docker docs on starting containers automatically.
Verifying it works
After setting the policy, confirm it:
docker inspect <container-name> --format '{{.HostConfig.RestartPolicy.Name}}'
It should now print unless-stopped.
To be sure, restart the Docker daemon and check the running containers:
systemctl restart docker
docker ps
The containers with unless-stopped should now be running.
What I learned
The mistake on my side was assuming Docker would bring containers back automatically. It doesn’t – it’s opt-in, per container. Since then, I set --restart unless-stopped on every container on that DEV server, and the next kernel-patch reboot came up clean with everything running.
