Ben Harrison
Ben Harrison

Reputation: 2219

Force a problematic docker container to restart itself?

I often run into an issue with some our docker container applications that the simple fix is to restart the docker container. Unfortunately this is a manual process, and we have broken functionality until we discover which container is problematic and needs to be rebooted. This has me wondering if there is a good technique for auto restarting docker containers in certain situations?

Right now I'm thinking of a combination of the --autorestart flag, along with forcing the application to close when it encounters a known-issue. However, I'm not sure if this is the best approach.

Upvotes: 4

Views: 12078

Answers (3)

Saad Rasool Butt
Saad Rasool Butt

Reputation: 61

Other than --restart=always and --restart=unless-stopped we also have --restart=on-failure[:max-retry] (Docker attempts to restarts the container if the container returns a non-zero exit code. You can optionally specify the maximum number of times that Docker will try to restart the container).

And we can also use Docker HEALTHCHECK instruction: It tells Docker how to test a container to check that it is still working. This can detect cases such as a web server that is stuck in an infinite loop and unable to handle new connections, even though the server process is still running. We can also restart containers using Healthcheck. [https://docs.docker.com/engine/reference/builder/#healthcheck][1]

Following are some examples that i have used to restart container and healing:

docker run -d \
    --name autoheal \
    --health-cmd='stat /etc/nginx/nginx.conf \
    --health-interval=2s \ 
    --restart=always \
    -e AUTOHEAL_CONTAINER_LABEL=all \
    -e DOCKER_SOCK=/var/run/docker.sock \
    -e CURL_TIMEOUT=15     \
    -v /var/run/docker.sock:/var/run/docker.sock \
    willfarrell/autoheal

docker run -d \
    --name autoheal \
    --restart=always \
    -e autoheal=true \
    -e AUTOHEAL_DEFAULT_STOP_TIMEOUT=10 \
    -e AUTOHEAL_INTERVAL=5   \
    -e AUTOHEAL_START_PERIOD=0   \
    -p 8080:8080 testing:latest

docker run -d --health-cmd='curl -sS http://localhost:80 || exit 1' \
    --health-timeout=10s \
    --health-retries=3 \
    --health-interval=5s \
      -p 8080:9080 testing:latest

Upvotes: 2

jdno
jdno

Reputation: 4364

If you're application is able to detect issues, you can easily have the container restart itself. The two important things are the --restart flag and that the application exists when it detects an issue.

Start the container in the background (-d) and set a restart policy:
docker run --restart unless-stopped -d [IMAGE] [COMMAND]

With the restart policy, you control what Docker does when the command exists. Using --restart unless-stopped tells Docker to always restart the command, no matter what the exit code of the command was. This way, you can have your application check its health, and if necessary use exit(1) or something similar to shutdown. When that happens, Docker will follow its restart policy and start a new container.

Although Docker doesn't really care about the return code, I would make sure that the application exists with a status code other than 0 to indicate an issue. This might be useful later if you do want to analyze logs or use your container from scripts.

Edit:

I initially used --restart always in the answer, but after some consideration I think it might be better to use --restart unless-stopped here. Its behavior is more predictable, because docker stop does actually stop a service. With --restart always, docker stop will stop the container, but then start a new one again, which isn't necessarily what you want or expect to happen.

Upvotes: 9

webdizz
webdizz

Reputation: 846

You can use next command to restart container:

docker restart $container

Upvotes: 0

Related Questions