Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stopping docker container from inside

Tags:

docker

I have a cronjob running inside a docker container that checks whether all services are running as expected. If this cronjob determines that there is a problem I would like to stop the docker container (from inside...)

Unfortunately exit just stops my cronjob script

like image 725
Nils Ziehn Avatar asked Jul 21 '15 11:07

Nils Ziehn


People also ask

How do you stop a container from inside?

Basically, you need PID 1 to exit to stop the container. I initially thought kill -s SIGKILL 1 would work, but PID 1 is protected, so it doesn't. As suggested by @Thomasleveil, you could add code such as trap "exit" SIGINT SIGTERM to the PID 1 script, which will mean the process will exit when sent a kill -s SIGINT 1 .

How do I stop a docker container?

docker rm -f The final option for stopping a running container is to use the --force or -f flag in conjunction with the docker rm command. Typically, docker rm is used to remove an already stopped container, but the use of the -f flag will cause it to first issue a SIGKILL.

How do I get out of a docker container without exiting it?

Detaching Without Stopping Docker supports a keyboard combination to gracefully detach from a container. Press Ctrl-P, followed by Ctrl-Q, to detach from your connection.


2 Answers

Basically, you need PID 1 to exit to stop the container.

I initially thought kill -s SIGKILL 1 would work, but PID 1 is protected, so it doesn't.

As suggested by @Thomasleveil, you could add code such as trap "exit" SIGINT SIGTERM to the PID 1 script, which will mean the process will exit when sent a kill -s SIGINT 1. I slightly prefer this method to the one you came up with (killing the child process directly) as it gives the parent process a chance to clean up and also the parent process should be able to find the PID of the child process without awk.

The easiest way to handle this is with some sort of supervisor process, and handily Docker now provide one called "tini". Just run add the argument --init to docker run and Docker will set up tini as PID 1 in the container. A full description is here: https://docs.docker.com/engine/reference/run/#specify-an-init-process

like image 103
Adrian Mouat Avatar answered Sep 25 '22 12:09

Adrian Mouat


I faced the same problem and I solved it by using healthcheck feature of docker.

You can add checks to verify your services in a file like heahthcheck.sh. Then append something like following to your Dockerfile :

# Healthcheck COPY healthcheck.sh / RUN chmod +x /healthcheck.sh  HEALTHCHECK --interval=10s --retries=5 CMD /healthcheck.sh 

This makes sure that docker checks the health of your container by running your script in specified interval and if it fails 5 times in a row, it marks the state unhealthy.

Now, in order to restart your container if the state goes unhealthy you can use autoheal like this:

docker run -d \     --name autoheal \     --restart=always \     -e AUTOHEAL_CONTAINER_LABEL=all \     -v /var/run/docker.sock:/var/run/docker.sock \     willfarrell/autoheal 

This will restart your container every time its state goes unhealthy.

like image 38
Lokesh Avatar answered Sep 22 '22 12:09

Lokesh