終了コマンドでシグナルが送られる

Dockerコンテナに対してdocker stopコマンドを実行するとデフォルトではSIGTERMが送られた後10秒後にSIGKILLが送られる。

シグナルを受け取ったタイミングでログを残すNode.jsスクリプトを作成し、

$ <<SCRIPT > main.js
'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(80, '0.0.0.0');
console.log('server started');
console.time('server received \`SIGTERM\`');
process.on('SIGTERM', function () {
  console.timeEnd('server received \`SIGTERM\`');
});
SCRIPT

Dockerコンテナのエントリポイントで実行して2秒後にdocker stopコマンドを送ることで確認できる。

$ <<DOCKERFILE > Dockerfile
FROM node
COPY ./main.js ./main.js
ENTRYPOINT ["node", "main"]
DOCKERFILE
$ docker build -t image .
$ { sleep 2 ; docker stop app > /dev/null } & disown ; TIMEFMT="server stopped by \`SIGKILL\`: %E" ; time docker run --rm --name app image
server started
server received `SIGTERM`: 1.809s
server stopped by `SIGKILL`: 12.23s

送信されるシグナルは変更できる

docker stopで送信されるシグナルはdocker runのオプション--stop-signalもしくはdocker-compose.ymlstop_signalで変更できる。

$ { sleep 2 ; docker stop app > /dev/null } & disown ; TIMEFMT="server stopped by \`SIGKILL\`: %E" ; time docker run --rm --name app --stop-signal 2 image
server started
server stopped by `SIGKILL`: 12.24s

強制終了までの猶予期間も変更できる

docker stopでシグナルが送信された後、SIGKILLが送信されるまでの猶予期間もdocker stopのオプション--timeもしくはdocker-compose.ymlstop_grace_periodで変更できる。

$ { sleep 2 ; docker stop -t 2 app > /dev/null } & disown ; TIMEFMT="server stopped by \`SIGKILL\`: %E" ; time docker run --rm --name app image
server started
server received `SIGTERM`: 1.694s
server stopped by `SIGKILL`: 4.22s