Supervisor を Docker で使う

注釈

sudo を使いたくなければルート以外でアクセスする方法 をご覧ください。

伝統的に Docker コンテナは起動時に1つのプロセスを実行します。例えば、Apache デーモンや SSH サーバのデーモンです。しかし、コンテナ内で複数のプロセスを起動したいこともあるでしょう。これを実現するにはいくつもの方法があります。プロセス管理ツールをインストールすることで、コンテナの CMD 命令で単純な Bash スクリプトを使えるようにします。

ここでは例としてプロセス管理ツール Supervisor を使い、コンテナ内で複数のプロセスを管理します。Supervisor を使うことにより、実行したいプロセスを再起動できます。デモンストレーションとして、SSH デーモンと Apache デーモンの両方をインストール・管理します。

Dockerfile の作成

基本的な Dockerfile から新しいイメージを作りましょう。

FROM ubuntu:16.04
MAINTAINER examples@docker.com

Supervisor のインストール

SSH や Apache デーモンと同様に、Supervisor をコンテナにインストールできます。

RUN apt-get update && apt-get install -y openssh-server apache2 supervisor
RUN mkdir -p /var/lock/apache2 /var/run/apache2 /var/run/sshd /var/log/supervisor

1つめの RUN 命令は openssh-serverapache2supervisor (Supervisor デーモンを提供)の各パッケージをインストールします。次の RUN 命令は SSH デーモンと Supervisor が必要な4つのディレクトリを作成します。

Supervisor の設定ファイルを追加

次は Supervisor の設定ファイルを追加しましょう。デフォルトのファイルは supervisord.conf であり、 /etc/supervisor/conf.d/ に置きます。

COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf

supervisord.conf ファイルの内容を見ましょう。

[supervisord]
nodaemon=true

[program:sshd]
command=/usr/sbin/sshd -D

[program:apache2]
command=/bin/bash -c "source /etc/apache2/envvars && exec /usr/sbin/apache2 -DFOREGROUND"

supervisord.conf 設定ファイルにはディレクティブ(命令)を記述します。これは Supervisor とプロセスを管理するためです。始めのブロック [supervisord] は Supervisord 自身の設定を指定します。ここで使ったディレクティブ nodaemon は、Supervisor をデーモン化するのではなく、インタラクティブに実行します。

次の2つのブロックは制御したいサービスを管理します。各ブロックは、別々のプロセスです。ブロックには command というディレクティブが1つあり、各プロセスで何のコマンドを起動するか指定します。

ポートの公開と Supervisor の実行

Dockerfile を仕上げるには、コンテナの実行時に必要な公開ポートや、 Supervisor 起動のための CMD 命令を追加します。

EXPOSE 22 80
CMD ["/usr/bin/supervisord"]

この命令は Docker に対してコンテナのポート 22 と 80 を公開するように伝え、そしてコンテナ起動時に /usr/bin/supervisord バイナリを実行します。

イメージの構築

Dockerfile は次のようになっているでしょう:

FROM ubuntu:16.04
MAINTAINER examples@docker.com

RUN apt-get update && apt-get install -y openssh-server apache2 supervisor
RUN mkdir -p /var/lock/apache2 /var/run/apache2 /var/run/sshd /var/log/supervisor

COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf

EXPOSE 22 80
CMD ["/usr/bin/supervisord"]

そして supervisord.conf は次の通りでしょう:

[supervisord]
nodaemon=true

[program:sshd]
command=/usr/sbin/sshd -D

[program:apache2]
command=/bin/bash -c "source /etc/apache2/envvars && exec /usr/sbin/apache2 -DFOREGROUND

これで、次のコマンドを使って新しいイメージを構築できます。

$ docker build -t <yourname>/supervisord .

Supervisor コンテナを実行

イメージを構築したら、これを使ってコンテナを起動します。

$ docker run -p 22 -p 80 -t -i <yourname>/supervisord
2013-11-25 18:53:22,312 CRIT Supervisor running as root (no user in config file)
2013-11-25 18:53:22,312 WARN Included extra file "/etc/supervisor/conf.d/supervisord.conf" during parsing
2013-11-25 18:53:22,342 INFO supervisord started with pid 1
2013-11-25 18:53:23,346 INFO spawned: 'sshd' with pid 6
2013-11-25 18:53:23,349 INFO spawned: 'apache2' with pid 7
. . .

docker run コマンドを実行することで、新しいコンテナをインタラクティブに起動しました。このコンテナは Supervisor を実行し、一緒に SSH と Apache デーモンを起動します。 -p フラグを指定し、ポート 22 と 80 を公開します。ここで、SSH と Apache デーモンの両方に接続できるようにするため、公開ポートを個々に指定しています。

参考

Using Supervisor with Docker
https://docs.docker.com/engine/admin/using_supervisord/