1️⃣ はじめに
Docker コンテナは、基本的に 1つのプロセス(PID 1)が終了するとコンテナも停止 します。そのため、nginx や sshd など複数のサービスを 1つのコンテナで動かしたい場合は、Supervisor を使ってプロセスを管理します。
2️⃣ Supervisorのメリット
- 複数プロセスの管理が簡単
→nginx や sshd など複数サービスを単一のコンテナで稼働させられる - プロセスの自動再起動
→プロセスが停止しても自動で再起動され、コンテナの安定稼働が可能 - フォアグラウンドでの管理
→Supervisor 自身を PID 1 とすることで、子プロセスを監視しつつコンテナが終了しない - ログの一元管理
→Supervisor が標準出力や標準エラーを管理できるので、ログの監視が簡単 - 設定が柔軟
→起動順序、依存関係、ユーザー権限などを設定ファイルで簡単に指定可能
3️⃣ Dockerfileの作成(CentOS 7 例)
CentOS 7 で nginx、sshd、Supervisor をインストールする例:
FROM centos:7.7.1908
# Vaultリポジトリに変更、yumタイムアウト延長
RUN sed -i 's|mirrorlist=|#mirrorlist=|g' /etc/yum.repos.d/CentOS-*.repo \
&& sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*.repo \
&& echo "timeout=300" >> /etc/yum.conf
# パッケージキャッシュの更新とインストール
RUN yum clean all && yum makecache fast
RUN yum install -y epel-release
RUN yum install -y openssh-server supervisor nginx
RUN yum clean all && rm -rf /var/cache/yum/*
# SSH鍵生成
RUN ssh-keygen -A
# Supervisor 設定をコピー
COPY supervisord.conf /etc/supervisord.conf
# ポートを公開
EXPOSE 22 80
# Supervisor をフォアグラウンドで起動
CMD ["/usr/bin/supervisord", "-n", "-c", "/etc/supervisord.conf"]
説明
- Vaultリポジトリに変更して CentOS7 の古いパッケージを入手可能にしています
- SSH と nginx を Supervisor で管理するためにインストール
- CMD で Supervisor をフォアグラウンド起動 (
-n) させ、コンテナの PID 1 としています
4️⃣ Supervisor 設定例(supervisord.conf)
[supervisord]
nodaemon=true
[program:sshd]
command=/usr/sbin/sshd -D
autostart=true
autorestart=true
user=root
[program:nginx]
command=/usr/sbin/nginx -g "daemon off;"
autostart=true
autorestart=true
user=root
説明
-
nodaemon=true:Supervisor 自身をフォアグラウンドで起動 -
sshd -Dとnginx -g "daemon off;":各サービスをフォアグラウンドで起動させ、Supervisor が終了を監視できる状態にする -
autostart=true/autorestart=true:コンテナ起動時に自動で立ち上がり、万が一停止しても自動再起動 -
user=root:CRIT 警告を回避するため root 権限で実行
5️⃣ コンテナのビルドと起動
ビルド
docker build -t c4supervisor .
説明
- Dockerfile の指示通りにイメージを作成
- nginx, sshd, Supervisor がインストールされた状態のイメージが完成
起動(ポート指定)
docker run -d -p 10022:22 -p 8080:80 --name c4supervisor c4supervisor
説明
-
-dでデタッチドモード(バックグラウンド)で起動 -
-p ホストポート:コンテナポートで外部にサービスを公開 - 起動直後、Supervisor が PID 1 となり nginx と sshd を管理
6️⃣ コンテナ内プロセスの確認
docker exec -it c4supervisor ps
出力例:
PID TTY TIME CMD
1 ? 00:00:00 supervisord
9 ? 00:00:00 nginx
10 ? 00:00:00 sshd
27 ? 00:00:00 ps
説明
- PID 1:Supervisor 自身(コンテナのメインプロセス)
- PID 9:nginx が Supervisor により管理され、フォアグラウンドで稼働
- PID 10:sshd が Supervisor により管理され、フォアグラウンドで稼働
- PID 27:この
psコマンド自身
7️⃣ kill コマンドでプロセスを停止させても再起動されることを確認
# nginx プロセスを停止
docker container exec c4supervisor kill 9
# sshd プロセスを停止
docker container exec c4supervisor kill 10
# 再起動後のプロセス確認
docker container exec c4supervisor ps
出力例:
PID TTY TIME CMD
1 ? 00:00:00 supervisord
18 ? 00:00:00 nginx
26 ? 00:00:00 sshd
27 ? 00:00:00 ps
説明
-
killで停止させた nginx (PID 9) と sshd (PID 10) は Supervisor によって自動再起動 - 再起動後の PID は異なる場合がありますが、Supervisor が常に子プロセスを監視していることを確認可能
出典
伊藤裕一著『たった1日で基本が身に付く Docker/Kubernetes超入門』技術評論社
P142~P145 chapter4 session4 Supervisorで複数の子プロセス(アプリ本体)を管理しよう