Docker コンテナ内で Apache と Laravel Queue Worker を同時に動かす
はじめに
仕事で Supervisor を使って Docker コンテナ内で Apache と Laravel Queue Worker を同時に動かすことがあったので、その作業記録としてこの記事を残します。 Supervisor ってのはこいつですね。複数のプロセスを監視、制御できるプログラムです。
設定
Dockerfile
まずは Dockerfile
の設定ですね。
FROM php:7.3-apache ... RUN apt-get install supervisor ... COPY ./docker/app/supervisord.conf /etc/supervisor/conf.d/supervisord.conf CMD ["/usr/bin/supervisord"]
ちなみに、php:7.3-apache の Docker イメージは以下のように ENTRYPOINT に docker-php-entrypoint
、CMD に apache2-foreground
を設定します。ENTRYPOINT と CMD を同時に指定するとENTRYPOINT 側を実行ファイル、CMD 側を引数にしてプログラムを実行します。
ENTRYPOINT ["docker-php-entrypoint"] ... CMD ["apache2-foreground"]
docker-php-entrypoint
は以下のようになっていて、-
で始まる引数を渡せば apache2-forground
にその引数を渡して実行し、それ以外は引数をそのまま実行します。
#!/bin/sh set -e # first arg is `-f` or `--some-option` if [ "${1#-}" != "$1" ]; then set -- apache2-foreground "$@" fi exec "$@"
なので、CMD をこちら側で再定義してやれば、docker-php-entrypoint
に実行させるコマンドを上書きできるというわけですね。
supervisord.conf
次に、supervisord.conf
です。
[supervisord] nodaemon=true [program:apache] command=/usr/local/bin/apache2-foreground redirect_stderr=true stdout_logfile=/dev/stdout [program:laravel-worker] command=php /var/www/html/artisan queue:work --tries=3 redirect_stderr=true stdout_logfile=/dev/stdout
ポイントとしては
- supervisord を nodaemon モードで動かす(daemon で動かすとコンテナがすぐ終了してしまうので)
- stdout と stderr を /dev/stdout に流して
docker-compose logs
コマンドでログを見れるようにしている
とこくらいですかね。
動作確認
上記の設定をした上で Docker コンテナを立ち上げ、コンテナ内に入ります。以下のように RUNNING 状態になっていると成功です。
$ supervisorctl status apache RUNNING pid 10, uptime 6:31:07 laravel-worker RUNNING pid 11, uptime 6:31:07
あまりに薄い Laravel 要素
Laravel の要素があまりにも薄いので Job と Queue を使うときのテストの tips でも書いておきます。Queue に Job が push されていることを確認し、さらに Job の処理を実行するには以下のように書けばいいです。
Queue::fake(); ... // Job を Queue に突っ込む処理 ... Queue::assertPushed(SomethingJob::class, function ($job) { $job->handle(); return <<check something>>; }); ... // Job の処理結果に依存する処理
おわりに
あまりにも Laravel 要素が薄いなこの記事