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
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.
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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With