Dockerコンテナの起動時に、postfixやらなんやらを自動起動させるのに手間取ったのでその方法についてまとめました。
先に結論を書くと、
supervisorでpostfixを起動させるのがおそらくベター
です。それについての記載となります。
後述する創生滅亡輪廻 postfixおよびその類似の現象で悩む人をちょっとでも壊劫させることができれば幸いです。
なお、本記事ではalpine3.10の想定です。
大枠の思想は他のディストリビューションでも変わらないので、
インストールやらプロセス起動部分だけ変換してください。
supervisorをインストール&CMDに指定
supervisorをインストールし、CMDで起動するプロセスに指定します。
前述の通り、彼が今回の肝です。
# postfix関連とsupervisorのインストール
RUN apk add --no-cache supervisor && \
postfix postfix-pcre && \
mailx cyrus-sasl cyrus-sasl-crammd5 rsyslog
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisord.conf"]
「なんやねんそれ」って人用にざっくり書くとフォアグラウンドプロセスをデーモン化したり管理したりするやつです。これをCMDに設定することで任意のプロセスを自動起動していきます。
今回フォアグラウンドプロセスって部分、超大事だった。
上の例では起動させるpostfixも一緒に入れてます。
supervisorの設定
次にデーモンとして起動させるプロセスとかの設定をします。
以下はpostfixを自動起動される例です。
# supervisord設定
RUN echo '[supervisord]' >> /etc/supervisord.conf && \
echo 'nodaemon=true' >> /etc/supervisord.conf && \
echo '[program:postfix]' >> /etc/supervisord.conf && \
echo 'command=postfix start-fg' >> /etc/supervisord.conf
- supervisorをnodeamonで起動し (nodaemon=true)
- postfixというプロセス名をつけて ([program:postfix])
- postfixをフォアグランドで起動しています (command=postfix start-fg)
これでコンテナを起動させればOKです。以下の様にpostfixが起動され、コンテナの標準出力でもそれが確認できるはずです。
# postfix status
postfix/postfix-script: the Postfix mail system is running: PID: 609
$ docker logs {コンテナ名}
2020-01-08 18:06:49,102 INFO supervisord started with pid 1
2020-01-08 18:06:50,109 INFO spawned: 'postfix' with pid 540
2020-01-08 18:06:51,172 INFO success: postfix entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
動けばいいよ!って人はここまで見ればいいです。
お疲れ!ビール飲んでいいよ!
supervisor設定のポイント
今回のポイントとしては以下の二点です。
- supervisorそのものはnodeamonで起動(nodaemon=true)
- postfixはフォアグランドでの起動を明示(command=postfix start-fg)
前者はそうしないと全部起動した後にdockerコンテナそのものが終了してしまうためです。
プロセスが全部終了するとコンテナも終了するので。
後者はsupervisorの特性に関連します。
わかりやすいのでDockerfileを以下の様に変更してみてください。
# echo 'command=postfix start-fg' >> /etc/supervisord.conf && \
echo 'command=postfix start' >> /etc/supervisord.conf && \
この状態でコンテナを起動して標準出力を確認すると、
以下の様にpostfixがspawned(誕生)→exited(死亡)→spawned→exitedと延々と繰り返すはずです。
2020-01-08 18:06:09,698 INFO spawned: 'postfix' with pid 477
2020-01-08 18:06:10,702 INFO success: postfix entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2020-01-08 18:06:10,725 INFO exited: postfix (exit status 1; not expected)
2020-01-08 18:06:11,732 INFO spawned: 'postfix' with pid 484
2020-01-08 18:06:12,734 INFO success: postfix entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
2020-01-08 18:06:12,756 INFO exited: postfix (exit status 1; not expected)
これが僕が割と長く悩んだ創生滅亡輪廻postfixです。
commandで指定したプロセスがバックグラウンドにまわると、supervisorがそのプロセスを補足できずに
「起動したけど終了した」と判断して再起動をかけ続けるみたいなんですね。
これを防ぐために、postfixをフォアグラウンド指定で起動しています。
余談
postfix start-fgはpostfixのバージョンが3.3以上でないと使えません。
そのため、もしそれ未満で同様のことがしたい場合は、以下の様にしてください。
# echo 'command=postfix start-fg' >> /etc/supervisord.conf && \
echo 'command=sh /usr/local/bin/postfix.sh' >> /etc/supervisord.conf && \ #postfix3.3未満の場合
#!/bin/sh
postfix start
tail -F /var/log/mail.log
supervisorではシェルを起動し、起動されるシェルの方でpostfixの起動とFオプション月のtailコマンドでフォアグランド扱いとする方式です。
こっちのが応用も効くかな?知らんけど。