Supervisor を Docker で入門する

supervisor を使ったことがないので理解したいと思います。

# 最終的には、以下の4つのファイルで、プロセスを二つ管理したいとおもいます。

```terminal
$ tree
.
├── Dockerfile
├── hello.sh
├── hey.sh
└── supervisord.conf
```

# まず適当に動かしてみる

ひとまず、supervisor を入れたコンテナを用意して、そのコンテナ内で supervisor の動きを確認してみます。

まず centos な環境で使いたかったので、Dockerfile を作成して、centos なイメージに pip いれて、それ経由で supervisor 入れます。

```dockerfile:Dockerfile
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` を打ちます。

```bash
[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` というファイルにコピペしてしまいます。

コメントアウトを消すと以下のような感じです。

```ini:supervisor.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
```

つぎに動かすプログラムを書きます、本当に少しです。

ひとまず、永久に動き続けるのを書いてみます。

```bash:hello.sh
#!/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` に配置して、コンテナ内で以下のコマンドを打つと動きます。

```bash
supervisor -c /etc/supervisord.conf
```

# Dockerfile の CMD で動かすようにする

```Dockerfile:Dockerfile
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
```

```hello.sh
#!/bin/bash

sleep 1
echo 'hello'
```

hey.sh も実質 hello.sh と同じ。

```ini:supervisord.conf
[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 コマンドでやっています。

```bash
# ビルド
$ 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
```

以上です。