Trapping signals in Docker containers

Signals

process.on('SIGTERM', function() {
console.log('shutting down...');
});

Signals in Docker

Usage: docker kill [OPTIONS] CONTAINER [CONTAINER...]

Kill a running container using SIGKILL or a specified signal

-s, --signal="KILL" Signal to send to the container
'use strict';var http = require('http');var server = http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(3000, '0.0.0.0');
console.log('server started');var signals = {
'SIGINT': 2,
'SIGTERM': 15
};
function shutdown(signal, value) {
server.close(function () {
console.log('server stopped by ' + signal);
process.exit(128 + value);
});
}
Object.keys(signals).forEach(function (signal) {
process.on(signal, function () {
shutdown(signal, signals[signal]);
});
});

Application is the foreground process (PID1)

FROM iojs:onbuild

COPY ./program.js ./program.js
COPY ./package.json ./package.json

EXPOSE 3000

ENTRYPOINT ["node", "program"]
$ docker build -t signal-fg-app .
$ docker run -it --rm -p 3000:3000 --name="signal-fg-app" signal-fg-app
$ docker kill --signal="SIGTERM" signal-fg-app
$ docker stop signal-fg-app
server stopped by SIGTERM

Application is the background process (not PID1)

FROM iojs:onbuild

COPY ./program.js ./program.js
COPY ./program.sh ./program.sh
COPY ./package.json ./package.json

RUN chmod +x ./program.sh

EXPOSE 3000

ENTRYPOINT ["./program.sh"]
#!/usr/bin/env bash
set -x

pid=0

# SIGUSR1-handler
my_handler() {
echo "my_handler"
}

# SIGTERM-handler
term_handler() {
if [ $pid -ne 0 ]; then
kill -SIGTERM "$pid"
wait "$pid"
fi
exit 143; # 128 + 15 -- SIGTERM
}

# setup handlers
# on callback, kill the last background process, which is `tail -f /dev/null` and execute the specified handler
trap 'kill ${!}; my_handler' SIGUSR1
trap 'kill ${!}; term_handler' SIGTERM

# run application
node program &
pid="$!"

# wait forever
while true
do
tail -f /dev/null & wait ${!}
done
docker build -t signal-bg-app .
docker run -it --rm -p 3000:3000 --name="signal-bg-app" signal-bg-app
docker kill --signal="SIGUSR1" signal-bg-app
docker kill --signal="SIGTERM" signal-bg-app

Conclusion

References

  1. Overview of signals http://man7.org/linux/man-pages/man7/signal.7.html
  2. Michael Kerrisk (2010), The Linux Programming Interface: A Linux and UNIX System Programming Handbook. No Starch Press

--

--

--

Software Developer

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Grigorii Chudnov

Grigorii Chudnov

Software Developer

More from Medium

Creating web server using HTTP Module and logging

Two way SSL encryption using nodejs

Creating a HTTP Server with NodeJS and logging requests with promised fs

Getting started with RabbitMQ