Case: we have a docker container that runs a bash script that needs to "block" forever (because it exposes a volume for another container, but there are other reasons why we sometimes want this).
I thought this could work then:
exec sleep infinity;
ps aux then gives "sleep" as PID 1. Great, I thought, then it will receive signals we send it from outside the container. For example:
docker kill -s INT container_name
But that doesn't work, container keeps running (also for SIGTERM). A normal kill does work, but I don't understand why there's a difference (which annoys me greatly):
docker kill container_name
Why can't I kill "sleep" with SIGINT/SIGTERM when it runs as PID 1 in my container? I believe I can kill other things (like bash scripts) with SIGINT/SIGTERM when they run as PID 1 in a container.
Would this be of any use? https://www.fpcomplete.com/blog/2016/10/docker-demons-pid1-orphans-zombies-signals
Basically the problem is process number 1. Linux/unix kernels are reluctant to signal that process the regular way, as it is supposed to be init. If init process dies, the system issues a panic immediately and reboots. If your process 1 does not have a handler to a signal, the signal just gets dropped. Sleep does not have handlers for any signals but you can build one to bash script.
Basically what you need to do is use exec form in your dockerfile, and split your sleep infinity into a loop as bash traps do not get triggered while shell is executing a command. This sends a signal to the running process 1 and catches it:
Dockerfile:
FROM ubuntu
ADD foo.sh /tmp
RUN ["/tmp/foo.sh"]
foo.sh:
#!/bin/bash
trap "echo signal;exit 0" SIGINT
while :
do
sleep 1
done
This will react to docker kill --signal=SIGINT.