supervisor を使ったことがないので理解したいと思います。
最終的には、以下の4つのファイルで、プロセスを二つ管理したいとおもいます。
$ tree
.
├── Dockerfile
├── hello.sh
├── hey.sh
└── supervisord.conf
まず適当に動かしてみる
ひとまず、supervisor を入れたコンテナを用意して、そのコンテナ内で supervisor の動きを確認してみます。
まず centos な環境で使いたかったので、Dockerfile を作成して、centos なイメージに pip いれて、それ経由で supervisor 入れます。
FROM centos:7
# こっちでもいい
# RUN yum install -y python-setuptools && \
# easy_install supervisor
RUN curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py && \
python get-pip.py && \
pip install supervisor
次に、config ファイルを作りたいのですが。雛形を生成するコマンドがあるので、それを使ってみます。
コンテナの中に入って echo_supervisord_conf
を打ちます。
[root@4e1290d0e494 /]# echo_supervisord_conf
; Sample supervisor config file.
;
; For more information on the config file, please see:
; http://supervisord.org/configuration.html
;
; Notes:
; - Shell expansion ("~" or "$HOME") is not supported. Environment
; variables can be expanded using this syntax: "%(ENV_HOME)s".
...以下略...
これをそのまま supervisord.conf
というファイルにコピペしてしまいます。
コメントアウトを消すと以下のような感じです。
[unix_http_server]
file=/tmp/supervisor.sock
[supervisord]
logfile=/tmp/supervisord.log
logfile_maxbytes=50MB
logfile_backups=10
loglevel=info
pidfile=/tmp/supervisord.pid
nodaemon=false
minfds=1024
minprocs=200
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///tmp/supervisor.sock
つぎに動かすプログラムを書きます、本当に少しです。
ひとまず、永久に動き続けるのを書いてみます。
# !/bin/bash
while :; do
echo "Hello, world!"
sleep 1
done
これを supervisor 経由で動かすには、supervisord.conf
に以下を追記します。
[program:hello]
command=/hello.sh
stdout_logfile=/tmp/hello.log
これでコンテナ内に、hello.sh
を /
に、supervisord.conf
を /etc
に配置して、コンテナ内で以下のコマンドを打つと動きます。
supervisor -c /etc/supervisord.conf
Dockerfile の CMD で動かすようにする
FROM centos:7
RUN curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py && \
python get-pip.py && \
pip install supervisor
COPY hello.sh /hello.sh
COPY hey.sh /hey.sh
COPY supervisord.conf /etc/supervisord.conf
CMD supervisord -c /etc/supervisord.conf
# !/bin/bash
sleep 1
echo 'hello'
hey.sh も実質 hello.sh と同じ。
[unix_http_server]
file=/tmp/supervisor.sock ; the path to the socket file
[supervisord]
logfile=/tmp/supervisord.log ; main log file; default $CWD/supervisord.log
logfile_maxbytes=50MB ; max main logfile bytes b4 rotation; default 50MB
logfile_backups=10 ; # of main logfile backups; 0 means none, default 10
loglevel=info ; log level; default info; others: debug,warn,trace
pidfile=/tmp/supervisord.pid ; supervisord pidfile; default supervisord.pid
nodaemon=true ; start in foreground if true; default false
minfds=1024 ; min. avail startup file descriptors; default 1024
minprocs=200 ; min. avail process descriptors;default 200
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL for a unix socket
[program:hello]
command=/hello.sh
stdout_logfile=/tmp/hello.log
autostart=true
autorestart=true
[program:hey]
command=/hey.sh
stdout_logfile=/tmp/hey.log
autostart=true
autorestart=true
重要なポイントは nodaemon=true
としている点です。これをしないとコンテナがすぐ終了しちゃいます。
動作の確認には以下のような docker コマンドでやっています。
# ビルド
$ docker build -t supervisor-image .
# ラン
$ docker run --name supervisor-container -d supervisor-image
# これでコンテナ内へ
$ docker exec -it supervisor-container bash
# プロセスを見てみる
[root@7cf591f95fbd /]# ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 1.4 0.9 115748 19948 ? Ss 07:33 0:00 /usr/bin/python /usr/bin/supervisord -c /etc/supervisord.conf
root 49 0.5 0.1 11836 2864 pts/0 Ss 07:33 0:00 bash
root 86 0.0 0.1 11696 2540 ? S 07:33 0:00 /bin/bash /hello.sh
root 87 0.0 0.1 11696 2668 ? S 07:33 0:00 /bin/bash /hey.sh
root 88 0.0 0.0 4372 692 ? S 07:33 0:00 sleep 1
root 89 0.0 0.0 4372 688 ? S 07:33 0:00 sleep 1
root 90 0.0 0.1 51760 3516 pts/0 R+ 07:33 0:00 ps aux
# ログを見てみる
[root@7cf591f95fbd /]# tail -f /tmp/hey.log
hey
hey
hey
hey
以上です。