Skip to content
Advertisement

Why does SIGHUP not work on busybox sh in an Alpine Docker container?

Sending SIGHUP with

JavaScript

to a busybox sh process on my native system works as expected and the shell hangs up. However, if I use docker kill to send the signal to a container with

JavaScript

it doesn’t do anything. The Alpine container is still running:

JavaScript

By the way, with an Ubuntu container (which runs bash) it does work as expected:

JavaScript

Sending SIGKILL does work, but I’d rather find out why SIGHUP does not.


Update: I’ll add another example. Here you can see that busybox sh generally does hang up on SIGHUP successfully:

JavaScript

However, running the same infinite sleep loop inside the docker container doesn’t quit. As you can see, the container is still running after SIGHUP and only exits after SIGKILL:

JavaScript

Advertisement

Answer

(I don’t have Docker env at hand for a try. Just guessing.)

For your case, docker run must be running busybox/sh or bash as PID 1.

According to Docker doc:

Note: A process running as PID 1 inside a container is treated specially by Linux: it ignores any signal with the default action. So, the process will not terminate on SIGINT or SIGTERM unless it is coded to do so.

For the differece between busybox/sh and bash regarding SIGHUP

On my system (Debian 9.6, x86_64), the signal masks for busybox/sh and bash are as follows:

busybox/sh:

JavaScript

bash:

JavaScript

As we can see busybox/sh does not handle SIGHUP so the signal is ignored. Bash catches SIGHUP so docker kill can deliver the signal to Bash and then Bash will be terminated because, according to its manual, “the shell exits by default upon receipt of a SIGHUP.


UPDATE 2020-03-07 #1:

Did a quick test and my previous analysis is basically correct. You can verify like this:

JavaScript

As I showed earlier, by default busybox/sh does not catch SIGHUP so the signal will be ignored. But after busybox/sh explicitly trap SIGHUP, the signal will be delivered to it.

I also tried SIGKILL and yes it’ll always terminate the running container. This is reasonable since SIGKILL cannot be caught by any process so the signal will always be delivered to the container and kill it.


UPDATE 2020-03-07 #2:

You can also verify it this way (much simpler):

JavaScript
User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement