Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Gracefully Stopping Docker Containers

I'm having some trouble to understand how I can do some cleanup when the container is stopped.

To make it easier, I prepared a sample to reproduce the problem.

Here are the contents of my files:

Dockerfile

FROM opensuse:latest

# Install tcsh (non-interactive mode)
RUN zypper -n in tcsh

# Create user
RUN useradd -ms /bin/tcsh dummyuser

# Set the user
USER dummyuser

# Change Working Dir
WORKDIR /home/dummyuser

# Copy entrypoint script
COPY docker-entrypoint.sh $HOME

# Starter Script
ENTRYPOINT ["./docker-entrypoint.sh"]

docker-entrypoint.sh

#!/bin/tcsh

echo "Starting"

onintr cleanup

# Running something in foreground, otherwise the container will stop
while (1)
   sleep 1000
end
exit 0

cleanup:
   onintr -
   echo "cleanup on going"
   exit 0

Make docker-entrypoint.sh executable:

chmod 744 docker-entrypoint.sh

Build the image:

docker build -t my-dummy-img .

Notice that I'm using tcsh shell.

If you take a look at the docker-entrypoint.sh you can see that I'm waiting to cath the interrupt (onintr cleanup) and call a cleanup method.

Now, these are the commands I run:

mstack/dummy-project> docker run --name my-service -ti -d my-dummy-img ps -eaf
da1dc21281a58e384f2ff34aa49a82019214e204e6d7a77ff54e8c96e005f913
mstack/dummy-project> docker logs my-service
Starting
mstack/dummy-project> docker stop my-service
my-service
mstack/dummy-project> docker logs my-service
Starting
mstack/dummy-project>

Here is the problem, I would expect that after the second docker logs my-service the output would be:

Starting
cleanup on going

Instead of only

Starting

Because docker is supposed to send a signal when stopping...

On the other hand, if I run:

docker run --name my-service-attached -ti my-dummy-img ps -eaf

And hit CTRL+C, I can see the expected output.

What am I missing here? I hope the question is clear enough.

BTW, I used the following to articles as guideline:

Gracefully Stopping Docker Containers

Trapping signals in Docker containers

like image 921
amp Avatar asked Mar 02 '17 19:03

amp


People also ask

How do I get out of the docker container without stopping it?

Docker supports a keyboard combination to gracefully detach from a container. Press Ctrl-P, followed by Ctrl-Q, to detach from your connection. You'll be dropped back into your shell but the previously attached process will remain alive, keeping your container running.

Is docker still relevant in 2022?

Momentum has definitely grown, and it's led us to some very humbling discoveries in 2022: Docker is the #1 most loved development tool, and remains the #1 most-wanted tool.

What is difference between docker kill and stop?

To terminate a container, Docker provides the docker stop and docker kill commands. Both the docker kill and docker stop commands look similar, but their internal execution is different. The docker stop commands issue the SIGTERM signal, whereas the docker kill commands sends the SIGKILL signal.


1 Answers

Finally solved the problem.

Tcsh shell doesn't receive most of the signals like SIGTERM which is the signal sent by docker when stopping the container.

So I changed the script to use bash shell and whenever I want to run a tcsh command I just do it like this:

/bin/tcsh ./my-command

So, my docker-entrypoint.sh is like this:

#!/bin/bash

# SIGTERM-handler this funciton will be executed when the container receives the SIGTERM signal (when stopping)
term_handler(){
   echo "***Stopping"
   /bin/tcsh ./my-cleanup-command
   exit 0
}

# Setup signal handlers
trap 'term_handler' SIGTERM

echo "***Starting"
/bin/tcsh ./my-command

# Running something in foreground, otherwise the container will stop
while true
do
   #sleep 1000 - Doesn't work with sleep. Not sure why.
   tail -f /dev/null & wait ${!}
done
like image 195
amp Avatar answered Oct 09 '22 05:10

amp