When I use the image with
CMD ["node", "app.js"]
and run my image with docker run -it, it does not reacts to SIGINT fired by Ctrl-C. I think it is because Node.js does not handle SIGINT when running as root process (as discussed in moby/moby#2838). It does not make sense to exit in this case generally, but it does when running in Docker.
Don't you have to specifically create a SIGINT handler, as noted in https://nodejs.org/api/process.html#process_signal_events?
Another alternative would be to use --init on your docker run line to have Docker automatically inject tini to give the default non-pid-1 behavior of SIGINT killing your process if it doesn't have a registered handler.
@tianon If the process is not running as root process, Node.js will catch the SIGINT for you. No need to write anything. I know I can write my own handler or resort to tini, but it would be great if this is the default behavior.
That's not Node.js catching SIGINT, that's the behavior of Linux around PID 1 -- if a non-1 PID doesn't capture a signal, the kernel will automatically kill the process instead. With PID 1, it will not do anything, and instead assumes the process must have a signal handler (because PID 1 is supposed to be an init system, typically).
@tianon Thanks for the info. Nevertheless we can have some sort of entrypoint to catch the signal right? Or is there some policy to keep the image Dockerfile-only?
I can't speak for the image maintainers, but I will point out that what you
describe is exactly what Docker's "--init" flag provides transparently.
Since kubernetes does not allow you to pass --init (at least it didn't a couple of years ago, might've changed) we use dumb-init as entrypoint in our images at work.
I think not deviating from standard docker practices makes sense here. Thanks for chiming in as always @tianon!
@nodejs/docker happy to reopen if you disagree
Most helpful comment
That's not Node.js catching
SIGINT, that's the behavior of Linux around PID 1 -- if a non-1 PID doesn't capture a signal, the kernel will automatically kill the process instead. With PID 1, it will not do anything, and instead assumes the process must have a signal handler (because PID 1 is supposed to be an init system, typically).