When I stop an upstart job, by default it uses SIGTERM. I have trapped SIGTERM in node.js like:
process.on('SIGTERM', shutdownServerGracefully);
process.on('SIGINT', shutdownServerGracefully);
I verified that this works by running it from terminal and sending kill -s SIGTERM [pid]
. This triggers the graceful shutdown, and I see it in logs.
I have an upstart script that looks like this:
# Process will start after a network is available.
start on runlevel [2345]
stop on runlevel [016]
# Keep server running
respawn
respawn limit 5 30
# Wait 5 minutes for server to gracefully shutdown
kill timeout 300
# Allow for graceful shutdown
kill signal SIGTERM
normal exit 0 SIGTERM SIGINT SIGQUIT
chdir /var/web_server
script
# Environment variables
. /etc/environment
export NODE_ENV
# Setup all stdout and stderr to go to a named pipe
mkfifo /tmp/log-fifo
( logger -t web < /tmp/log-fifo & )
exec > /tmp/log-fifo
rm /tmp/log-fifo
node server.js --env="$NODE_ENV" 2>&1
end script
When I start the job, everything works fine. When I stop the job, the node process is killed immediately, node never handles the SIGTERM signal.
If I change the upstart conf to kill signal SIGINT
, the node process WILL get SIGINT and shutdown gracefully. WTF?
Why does SIGINT work correctly but not SIGTERM? Why is my node process perfectly able to trap SIGTERM when run from terminal, but not when run via Upstart, and yet it is able to trap SIGINT? Is this a quirk or bug in Upstart?