ウェブアプリケーションなどをコンテナ管理するためにDockeを使うとき、docker run
の引数を処理できるように、Dockerfile
の中で本体のプロセスを直接ENTRYPOINT
やCMD
に指定するのではなくdocker-entrypoint.sh
から起動する場合も多いのではないでしょうか。
そのとき、以下のように書いたらダメです。「何がアカンの?」という方、今まで普通にこういう書き方をしていた方はご注意。ちなみに「set -eu
をつけろ!」とかそういう話ではないです。
#!/bin/bash
# 引数を処理したり色々
...
# 本体のプロセスを起動
/path/to/some-process
いやまあこれでも動くんですが、docker stop
やCtrl-C
などでコンテナを止めようとしたときに10秒ほど待たされます。これは、コンテナに対するSIGTERM
やSIGINT
がdocker-entrypoint.sh
が動いているプロセスにしか届かず、本体のプロセスまで送られません。そのため、Dockerはコンテナを止めたいのに本体のプロセスが止まってくれず、10秒のタイムアウトの後に強制的にプロセスを終了するという流れです。
ではどうすればいいかというと、ハイそうです。docker-entrypoint.sh
のプロセス自体を本体のプロセスで置き換えれば解決。というわけでexec
を使いましょう
exec /path/to/some-process
#!/bin/bash
# 引数を処理したり色々
...
# 現在のプロセスを本体のプロセスで置き換える
exec /path/to/some-process
これでDockerからは本体のプロセスになるので、コンテナを止めたときに本体のプロセスがすぐ止まるようになります。めでたしめでたし。