Docker Run Script to catch interruption signal
Asked Answered
C

1

5

I've a docker-compose.yml which starts several containers. One of which uses a Dockerimage file to install everything needed in that container.

I'd like to add a script which runs each time waiting for the interruption signals 0, 9 and 137.

Now, I'm trying to run the script as an Entrypoint in the Dockerimage file, but doesn't seems to work.

This is the content of the Dockerimage file :

RUN apt-get update && [...]
WORKDIR "/application"
ENTRYPOINT ["/bin/bash", "-c", "/application/scripts/cl.sh"] 

Am I doing something wrong? Do I need to rebuild the containers with the following command?

docker-compose build

This is the content of the bash script cl.sh

#!/bin/bash

echo "HELLO HELLO HELLO HELLO"

trap 'echo "Exiting with a 137 signal."' 137 0 9

The only purpose of the script at the moment is testing everything work.

Cycloid answered 9/5, 2018 at 16:20 Comment(6)
Please include a minimal reproducible example, including a shell script and command/method you use to send signals. More than likely the issue is the extra /bin/bash process you're including as pid 1, but I'd like to test this before posting an answer.Skeleton
@Skeleton I added the script content as it is. As you can see it's just for testing it's working properly the connection with the Docker system.Cycloid
Is your container still running to trap the signal? After you define the trap, your script immediately ends, which would end the container.Skeleton
My container still running with no problem.. I was expecting to find some message when I stop the container with the 'docker-compose stop' command.. But nothing shows in the logsCycloid
I didn't test your whole example, but regarding the ENTRYPOINT command of your Dockerfile, the bash option -c is off-topic and should be removed, because this option is dedicated for passing inline code to bash, not for running an external script.Publicly
Cool! Now is working but as you said, the container stops when the script run. Any idea how can I catch the interruption signal? The idea is to run a backup before the container stops.Cycloid
P
8

Yes it is possible to achieve what you want, but before presenting the corresponding code I have to comment on your question's code which contained some issues:

  • The line trap 'echo "Exiting with a 137 signal."' 137 0 9 is incorrect because 137 is not a valid signal number (see for example the Wikipedia article on signals).

    Maybe you just encountered 137 as it is the exit code corresponding to the signal 9 (given that 137 = 128 + 9, see this appendix in the bash doc.)

  • 0 (EXIT) and 9 (KILL) are valid signal numbers, but in practice it is better to only trap 2 (INT) and 15 (TERM), as suggested in this SE/Unix answer.

    Indeed while the INT and TERM signals can be used for "graceful termination", the KILL signal means the process must be killed immediately and as mentioned in man trap:

    Setting a trap for SIGKILL or SIGSTOP produces undefined results. […] Trapping SIGKILL or SIGSTOP is syntactically accepted by some historical implementations, but it has no effect. Portable POSIX applications cannot attempt to trap these signals.

  • Setting the trap at the end of the entrypoint script is a bad strategy, as it is useless in this place. Instead, I suggest that you define a cleanup function (the last instruction of which being exit), then set a trap on this function at the beginning of the script, and run your (non-terminating) application afterwards.

Hence the following proof-of-concept:

Dockerfile

FROM debian:latest
WORKDIR /app

COPY entrypoint.bash ./
ENTRYPOINT ["/bin/bash", "./entrypoint.bash"]

entrypoint.bash

#!/bin/bash

cleanup() {
    echo "Cleaning up..."
    exit
}

trap cleanup INT TERM

while :; do
    echo "Hello! ${SECONDS} secs elapsed..."
    sleep 1s
done

To test it, you just need to run:

$ docker build -t test-trap .
$ docker run -d --name=TEST-TRAP test-trap
  # wait a few seconds
$ docker stop TEST-TRAP
$ docker logs -f TEST-TRAP
Hello! 0 secs elapsed...
Hello! 1 secs elapsed...
Hello! 2 secs elapsed...
Hello! 3 secs elapsed...
Cleaning up...
Publicly answered 10/5, 2018 at 17:48 Comment(1)
@LuigiT. did the proposed answer work for you?Publicly

© 2022 - 2024 — McMap. All rights reserved.