SupervisorでPythonのWebSocketプログラムをお手軽に常駐化

# 【1】この記事の要約（・８・）

WebSocketを用いたチャットサーバをPythonで開発した案件。
デプロイする直前までpythonコマンドで起動してテストしてたことに気づかず、
「APサーバ使ってないの？　どうしよう...」
ってなった時に[Supervisor](http://supervisord.org/)で常駐化して乗り切ったお話です。

Supervisorの本来の価値はもっと別のところにあると思いますが、
そこは多くの方が有用な記事を書いて下さってますので、
[supervisorタグ](https://qiita.com/tags/supervisor)を追ってみて頂ければと。

# 【2】登場人物（人ではない）
GCE （OS：CentOS7）
Python 3.7.3
Supervisor 3.4.0

# 【3】準備

## 3.1. Python3.7インストール

- 本題じゃないので、以下記事に分けてます
    - [Python3.7をソースコードからインストール](https://qiita.com/Terutomi-B/items/a68f1cc7d13af56bab92)

- 以降、python3とかpip3とかコマンドが登場しますが、上記記事でシンボリックリンクを作成してあります

## 3.2. チャットプログラム配備

（この記事の本題じゃないので、後々関係あるところだけ記載します）

(1) モジュール置き場を作成

```
sudo mkdir /opt/chatsrv
```
(2) gitからcloneする
(3) 依存関係をインストールする
(4) サーバ実行

```
sudo python3 app.py
```

(5) 疎通確認

# 【4】Supervisorインストール

## 4.1. インストール

(1) pipインストール

```
sudo pip3 install git+https://github.com/Supervisor/supervisor
```

(2) シンボリックリンク作成

```
cd /usr/bin
sudo ln -s /usr/local/bin/echo_supervisord_conf .
sudo ln -s /usr/local/bin/pidproxy .
sudo ln -s /usr/local/bin/supervisorctl .
sudo ln -s /usr/local/bin/supervisord .
```

(3) ディレクトリ、ファイル準備

```
sudo mkdir /etc/supervisord.d
sudo mkdir /var/log/supervisor
sudo sh -c "echo '/var/log/supervisor/*.log {
       missingok
       weekly
       notifempty
       nocompress
}' > /etc/logrotate.d/supervisor" 
```

## 4.2. 設定

あとでまとめるとこれだけなんですが、何気に試行錯誤の時間がありました。
結構ハマりポイントだと思います。

### supervisord.conf

```/etc/supervisord.conf
...
[unix_http_server]
file=/tmp/supervisor.sock   ; the path to the socket file
...
[inet_http_server]         ; inet (TCP) server disabled by default
port=127.0.0.1:9001        ; ip_address:port specifier, *:port for all iface
...
[supervisord]
logfile=/var/log/supervisor/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=/var/run/supervisord.pid
nodaemon=false               ; 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
...
[include]
files = /etc/supervisord.d/*.ini
```

- 最後にある[include]セクションで、iniファイルを置く場所を変更してます
- 対象プログラムが増える都度、iniファイルを増やす設計ですね

### デーモン化する対象プログラム用のiniファイル

```/etc/supervisord.d/mychatsrv.ini
[program:mychatsrv]  ; プロセスの名前
directory=/opt/chatsrv  ; 作業ディレクトリ
command=/usr/local/bin/python3.7 /opt/chatsrv/app.py ; 起動コマンド
numprocs=1  ; 起動インスタンス数？
autostart=true  ; autostartする
autorestart=true  ; 自動で再起動させる
user=root  ; 起動ユーザ
redirect_stderr=true  ; 標準エラーを出力する
stdout_logfile=/var/log/supervisor/mychatsrv.log  ; ログファイルの出力先
```

- バージョンによって違うのか、参考サイトのサンプルのままだとダメだったりで試行錯誤でした

### supervisord.service

```/etc/systemd/system/supervisord.service
[Unit]
Description=Supervisord

[Service]
ExecStart=/usr/bin/supervisord -n

[Install]
WantedBy=multi-user.target
```

## 4.3. サービス実行

(1) 実行できる状態にあること（リストにいること）を確認

```
sudo systemctl list-unit-files --type=service
```

(2) 実行

```
sudo systemctl start supervisord
sudo systemctl status supervisord
```

(3) サービス有効化

```
sudo systemctl enable supervisord.service
```

# 【5】終わりに

以上で、OS再起動しても勝手にpythonコマンドで実行してくれて
常駐してくれる形になりました。
今回の作業的にはAPサーバ立てておけばという感じですが、
Supervisorのお手軽に常駐化できるところは使い道が色々ありそうです。

この記事書く時に気づいたんですが、今はバージョンも4系に上がっているようで、
また違った動きをするかも知れません。その点はご注意ください。