Dockerでsupervisordを使わずに複数デーモンを起動する方法

17a5fc2d2c401f995dbbe524f894c494_s

例によって Docker の話。

  • 「コンテナ内でApache と Postix 両方動かしたいぜ!」
  • 「nginxだからPHP使うのに php-fpm も動かさないとね!」

のように、複数のデーモンをコンテナ内で起動したいというのはよくある話。
でも、Docker は Dockerfile の最後に CMD で(または docker run で)指定した フォアグラウンド動作のプロセスしか起動しっぱなしにできません…。

Dockerfileで、

FROM centos:6.5
    :
CMD ["/usr/sbin/httpd -D FOREGROUND"]

みたいなことをしないと、最後に指定したApacheしか動かないわけです。

それで、代わりに使われてるのが Python製の「supervisord」。
CMD/usr/bin/supervisord を立ち上げると /etc/supervisord.conf に 並べた実行ファイルを起動しっぱなしにしてくれる。

supervisord.conf を適当に書くとこんな感じ。

[supervisord]
    :
[program:httpd]
command=/usr/sbin/httpd -D FOREGROUND

[program:mysqld]
command=/usr/bin/mysqld_safe

これだと Apache と MySQL を同時起動してくれます。

でも、正直めんどくさいよねー。

  • そもそもデーモンをフォアグラウンドで動かす方法を調べるのがめんどう
  • Pythonがいやだ(おい)。いや、だって、easy_install とかいっぱいあって…

ということで、もっと手抜きをする方法を考えました。
あっけにとられるくらい簡単。 コンテナ内に デーモンを起動するコマンドを羅列して sleep するシェルスクリプト を書き、 CMD で指定するだけ。

たとえばこんな感じ。/etc/services.sh として置いておきます。

#!/bin/sh
/sbin/service httpd start
/sbin/service mysqld start
/sbin/service crond start

while true
do
    sleep 10
done

sleep はもっと大きめのインターバルを取ったほうが負荷が低いのかも。

ということで、これを Dockerfile の CMD に指定するなり docker run で呼ぶなりしてください。ね。あっけないですね。

ちなみに supervisord を捨ててこの路線に乗り換えたのは、 crond をフォアグラウンドで動作させる方法がわからなかったからです…。