ECSでSupervisorを利用する

環境・プラットフォーム

例えば、Supervisorを使ってQueueに入ったJobを処理するWorkerサーバーを構築したり、CRON等で定期実行処理を行うSchedulerサーバーを構築したりする場合がよくあると思います。

本記事ではECS上でSupervisorを利用してLaravelのWorkerやSchedulerを構築する方法を解説します。
それぞれartisanコマンドの queue:work や schedule:work をSupervisorによって実行&監視するイメージになります。

Supervisorの設定ファイルを作成

さっそくSupervisorの設定ファイルを解説します。

下記ファイルを 「/etc/supervisor/conf.d」配下に設置することで、Supervisorが起動した際に自動的に必要なプロセスを起動してくれます。

[program:scheduler]
command=php /var/www/html/artisan schedule:work

# プロセス名を指定します("scheduler_00" のようになります)
# また "supervisorctl status" コマンドで実行中のプロセスを確認することができます
process_name=%(program_name)s_%(process_num)02d

# 並列で立ち上げるプロセス数を指定します
# Schedulerなので、並列実行する必要がないため1つにしています
numprocs=1

# trueに設定するとsupervisordが起動した際に自動でプロセスが開始されます
autostart=true

# プロセスが停止した際に自動で再開されます
autorestart=true

# このプロセスの実行ユーザーを指定します
# php-fpmでの実行のためwww-dataユーザを指定しています
user=www-data

# ログ出力の設定(詳しくは後述)
stdout_logfile=/proc/1/fd/1
stdout_logfile_maxbytes=0
stderr_logfile=/proc/1/fd/2
stderr_logfile_maxbytes=0

# プロセス が Supervisord に SIGCHLD を返すまで待機する秒数を指定します
# 詳しくは後述
stopwaitsecs=3600

# ここからはWorkerの設定です
[program:worker]
command=php /var/www/html/artisan queue:work
process_name=%(program_name)s_%(process_num)02d
numprocs=5
autostart=true
autorestart=true
user=www-data
stdout_logfile=/proc/1/fd/1
stdout_logfile_maxbytes=0
stderr_logfile=/proc/1/fd/2
stderr_logfile_maxbytes=0
stopwaitsecs=3600

stdout_logfile=/proc/1/fd/1 について

`docker logs <container>` コマンドで特定コンテナのログを出力することができますが、その出力対象はメインプロセス(PID1)の標準出力のみとなっており、stdout_logfile設定ではPID1の標準出力である /proc/1/fd/1 を指定しています(標準エラー出力は/proc/1/fd/2)。またECSのログドライバーである awslogs は docker logsの出力を受け取ってCloudWatchにログを転送しています。

ここでいうメインプロセス(PID1)とは、CMDによって起動されるプロセスのことを指します。

ちなみに/dev/stdout(デバイスの標準出力)は現在のプロセスの標準出力であり、Dockerは拾いませんし、awslogsも拾いません。

stopwaitsecs=3600 について

サーバー再起動などでプロセスに対して停止信号(SIGTERM)が送信されます、この信号を受け取ったプロセスは現在実行している処理が完了したら正常終了(SIGCHLD)としプロセスを停止します。このとき中途半端にプロセスが無理やりKILLされてしまうとデータに不整合が出たりして危険です、そのためこの設定で正常終了を待つ秒数を指定します。

Dockerfileを作成

Supervisorの設定ファイルができたので、あとはDockerfileを作成します。
Laravelのセットアップをして、php-fpmとSupervisorの起動をするだけです。

以下はDockerfileの例です。

FROM php:8.0-fpm
WORKDIR /var/www/html

# 必要なパッケージをインストール
RUN apt-get update && apt-get install -y \
    build-essential \
    libpng-dev \
    libjpeg62-turbo-dev \
    libfreetype6-dev \
    locales \
    zip \
    unzip \
    curl \
    sudo \
    libzip-dev && \
    docker-php-ext-install zip && \
    docker-php-ext-install mysqli && \
    docker-php-ext-enable mysqli && \
    docker-php-ext-install pdo pdo_mysql pcntl && \
    apt-get -y --purge remove build-essential && \
    apt-get clean && rm -rf /var/lib/apt/lists/* && \
    mkdir -p /var/www/html && \
    chown www-data:www-data /var/www/html
RUN pecl install redis && docker-php-ext-enable redis

# PHPの設定ファイルを追加
ADD .ci/docker/php.ini /usr/local/etc/php/conf.d/local.ini
ADD .ci/docker/www.conf /usr/local/etc/php-fpm.d/www.conf

# Supervisorをインストール&設定
RUN docker-php-ext-install pcntl && \
    apt-get update && \
    apt-get install -y supervisor
COPY .ci/docker/supervisord.conf /etc/supervisor/conf.d/supervisord.conf

# 後ほど解説
COPY .ci/docker/startup.sh /startup.sh
RUN chmod +x /startup.sh

# LaravelソースコードをDockerコンテナ内にコピー
COPY --chown=www-data:www-data {Laravelソースコードの場所} /var/www/html

# 必要なPHPライブラリをインストール
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
RUN sudo -u www-data composer install \
    --no-interaction \
    --prefer-dist \
    --no-dev \
    --optimize-autoloader

EXPOSE 9000
CMD ["/bin/bash","-c","/startup.sh"]

startup.sh」について、コンテナが起動したときの実行ファイルとして「CMD」に設定しています

以下はstartup.shの内容です。

#! /bin/bash

# このスクリプト内でエラーがあった場合に即座に処理が失敗するようにする
set -e

# Laravelのマイグレーション実行
cd /var/www/html/
sudo -E -u www-data php artisan migrate --force

# Supervisorを起動、設定ファイルに従って必要なプロセスが起動します。
supervisord -c /etc/supervisor/supervisord.conf

php-fpm

このDockerfileをCodePipelineまたはGitHub Actionsでビルドし、ECRにプッシュし利用します。



オフショア開発ならCRAID!

オフショア開発とは、システム開発業務などを海外の開発会社や海外子会社に委託することです。

CRAIDは東証プライム上場のフリービット株式会社の子会社です。CRAIDのオフショア開発拠点「フルスピードテクノロジーズ」は、当初は月間3000億ものリクエスト処理にも対応できる自社システム開発を行うためのオフショア開発部門として始まりました。各グループ会社の開発やクライアント様の受託開発やラボ型開発も多く手掛けております。

CRAIDやオフショア開発に関して、お気軽にお問い合わせください。

この記事を書いた人

社内経歴としては、社内システムの開発・保守から始まり、セブ開発拠点の立ち上げメンバーとしてフィリピン駐在、その後日本に帰国し受託開発やオフショア開発事業に参画し、様々な開発プロジェクトに参加しております。

taroshinをフォローする
環境・プラットフォーム開発技術
CRAID オフショア開発ブログ
タイトルとURLをコピーしました