Look at this c program:
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
int stop = 0;
void handle_signal(int sig)
{
stop = 1;
}
void main() {
signal(SIGINT, handle_signal);
signal(SIGTERM, handle_signal);
while (stop==0) {
printf("Hellon");
sleep(1);
}
}
I am compiling this program statically:
gcc -static test.c -o test
And I am creating this Dockerfile:
FROM scratch
COPY test /test
ENTRYPOINT ["/test"]
I am building the docker image:
docker build -t myimage .
Finally, I run a container from this image:
docker run --name mycontainer myimage
I have a problem: It is impossible to stop this container.
I have tried:
- CTRL-C
- docker stop mycontainer
- docker kill mycontainer
- exiting c loop when the program receives unix signals.
I am running Docker version 20.10.25 under kali Linux. gcc version: 13.3.0
I have this error when I try to run:
docker kill --signal=SIGINT mycontainer
Cannot kill container xxxx: Unknown error after kill: runc did not
terminate successfully: exit status 1: unable to signal init:
permission denied.
Please note there is only 1 file in my container. I have nothing else (bash, sh, …)
My goal is to understand why the program is not exiting and why the container is not stopping.
Do you have any idea ? What’s wrong in what I have done ?
Thanks
2
Answers
Maybe the program is not exiting, and the container is not stopping because processes running as PID 1 in Linux ignore default signals like
SIGTERM
andSIGINT
unless explicitly handled.If this is the problem, the solutions is to use a minimal init system like tini to properly forward signals.
Modify your Dockerfile to include
tini
:This ensures that signals are correctly forwarded to your program, and the container will stop as expected.
In a container built from scratch, there’s no init system or shell to properly handle signals. Your program becomes PID 1 inside the container, which behaves differently regarding signal handling. I would use a minimal base image like alpine if using tini as a lightweight init system failed.
So instead of scratch, alpine that includes an init system: