ウェブアプリケーションなどをコンテナ管理するために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からは本体のプロセスになるので、コンテナを止めたときに本体のプロセスがすぐ止まるようになります。めでたしめでたし。