-
Notifications
You must be signed in to change notification settings - Fork 7.3k
Node v0.11.16 doesn't exit on SIGTERM when runs inside Docker #9131
Comments
The change in behavior was introduced by c61b0e9. With this commit, when a user sends SIGINT by pressing CTRL-C in a terminal where node is the foreground process, the node process doesn't exit explicitly and instead forward the signal. The reason why this change has an impact on how a node process behaves within a node container is that, when using the "exec" form of the Dockerfile
the node process has the pid 1, and thus cannot be killed by SIGINT or SIGTERM. So forwarding the signal to itself is not sufficient for node to exit. However, if one uses the "shell" form of the Dockerfile
then the pid of the node process within the container is not 1, and forwarding the SIGINT signal works as expected, that is the process exits properly. I believe the correct issue to track in the docker repository is moby/moby#2436. Closing as it seems to be an issue with docker with an easy workaround, but please feel free to continue the discussion if this solution does not fix your issue. Thank you! |
@misterdjules, thank you for explanation! I was unaware of this feature of Unfortunately, the "shell" form of But process.on('SIGTERM', function() {
console.log('\ncaught SIGTERM, stopping gracefully');
process.exit(1);
});
console.log('lauched'); process.stdin.resume(); Dockerfile: FROM node:0.11.16
COPY index.js /app/
CMD node /app/index.js Trying to stop: # (terminal 1)
$ docker build -t 'test' . && docker run --rm -it --name 'test-app' 'test'
launched
# (terminal 2)
$ docker exec 'test-app' ps
PID USER TIME COMMAND
1 root 0:00 /bin/sh -c node index.js
7 root 0:00 node index.js
12 root 0:00 ps
$ docker kill -s TERM 'test-app'
# the app doesn't recieve the signal and continues to run
$ docker kill -s INT 'test-app'
# same here
$ docker exec 'test-app' kill -s INT 1
$ docker exec 'test-app' kill -s TERM 1
# no reaction
$ docker stop 'test-app'
# the app doesn't recieve SIGTERM and continues to run, and gets killed
# with SIGKILL after a timeout; nothing is printed in terminal 1 The only easy fix I see here is to use the "exec" form of Now it's clear to me that this is a Docker issue, and that Docker should run a special process as each container's |
Thank you @skozin for your great writeup about this issue. I'm sure other users of docker and Node.js will find it very useful! |
My solution for the PID1 problem: The Dockerfile ends with:
Than I run with this shell script, which has the filename of
The trick is So Here is my Dockerised Node.js development environment: https://github.com/DJviolin/Node.js-Development-Environment |
Based on this issue: - nodejs/node#4182 This is the proposed explanation and fix: - nodejs/node-v0.x-archive#9131 (comment)
Dockerfile:
index.js:
This app will ignore
TERM
andINT
signals, so it cannot be terminated usingCtrl+C
ordocker stop
. Tested with Docker 1.4.1, Linux kernel 3.16.7.Other configurations:
It appears that Node actually recieves and handles these signals, but for some reason doesn't perform the default action. This can be verified by adding signal listeners in
index.js
:It correctly prints
Caught SIG{INT,TERM}
and exits.Initially I posted this to docker-node repo, but moved it here as it seems unrelated to the particular Docker image.
The text was updated successfully, but these errors were encountered: