フォアグラウンドにできないコマンドへの対処

例えばhttpdコマンドはデフォルトでバックグラウンド実行だが、httpd -D FOREGROUNDとすればフォアグラウンド実行にできる。

コンテナはバックグラウンドのプロセスだけだとすぐ停止してしまうので、フォアグラウンドにできないコマンドを継続させる方法の例。


「tail -f /dev/null」でコンテナ継続

次のように、フォアグラウンドのコマンドとしてtail -f /dev/nullなどを加えるという方法がある。

# 単なるhttpdはバックグラウンド
docker run --rm -dit --name test --publish 80:80 httpd:2.4 httpd

# すぐに停止してしまう
docker ps --filter=name=test

# フォアグラウンドのコマンドを追加
docker run --rm -dit --name test --publish 80:80 httpd:2.4 bash -c " \
 httpd; \
 tail -f /dev/null"

# tailがあるのでサーバ継続
curl localhost
<html><body><h1>It works!</h1></body></html>

# コンテナ停止・削除(時間計測)
time docker stop --time=5 test
real 0m6.363s

プロセスID1にならないことに注意

このやり方だと、上の例のように、コンテナ停止まで--time以上の時間がかかっている。以下のように本来のやり方にすると、httpdのプロセスIDが1になって、docker stopによるSIGTERMを受け取れて、停止時間も早い。(コンテナ終了シグナルとSTOPSIGNAL)

# httpdのフォアグラウンド
docker run --rm -dit --name test --publish 80:80 httpd:2.4 httpd -D FOREGROUND

docker exec -it test ps -A --format pid,ppid,user,args
  PID  PPID USER     COMMAND
    1     0 root     httpd -D FOREGROUND
    7     1 daemon   httpd -D FOREGROUND
    8     1 daemon   httpd -D FOREGROUND
    9     1 daemon   httpd -D FOREGROUND
   97     0 root     ps -A --format pid,ppid,user,args

# コンテナ停止・削除(時間計測)
time docker stop --time=5 test
real 0m1.035s