カテゴリー
Linux

Docker イメージ php:7.4.5-apache で Apache の他に cron も動かす方法

はじめに

oki2a24/sample_dockerized_laravel6: Laravel6 を Docker 化するサンプルです。 にて Laravel を Docker コンテナ化しました。

Apache 入りの PHP コンテナで Laravel を動かしています。この Laravel で タスクスケジュール 6.x Laravel も行いたいと思いました。

cron を動かせば簡単です。

しかし、 コンテナではすでに Apache のプロセスが動いており、ここに cron を足せません。

これを、なんとかしたのが本投稿となります。

まとめ

ステップ 1. Supervisor で今まで動いている apache2-foreground を動かす

次を足しました。

Dockerfile

RUN apt-get update && apt-get install -y \
  supervisor \
  && apt-get clean \
  && rm -rf /var/lib/apt/lists/*
RUN mkdir -p /var/log/supervisor
COPY ./docker/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
CMD ["/usr/bin/supervisord"]

docker/supervisord.conf

[supervisord]
nodaemon=true

[program:apache2]
command=/usr/local/bin/apache2-foreground

apache2-foreground の特定方法は、 php/Dockerfile at master · docker-library/php を当たりました。

そして、コンテナ内で apache2-foreground のパスを type コマンドで特定いたしました。

cron をインストールするのをコンテナ内で試す

  • busybox-static をインストール
  • /var/spool/cron/crontabs/root という cron 設定ファイルを設置
apt update && apt install -y busybox-static
cat <<'EOT' > /var/spool/cron/crontabs/root
* * * * * echo '=== hello! ==='
EOT
busybox crond -L /var/log/cron

/var/log/cron に毎分指定した内容が実行されていることが確認できました。ただし、指定した内容の結果は、分かりませんでした。

cron を Supervisor に登録して動かす時に直面した問題

/var/spool/cron/crontabs/root

* * * * * echo '=== environment variables ===' && env

/etc/supervisor/conf.d/supervisord.conf には次を追記。

[program:crond]
command=/bin/busybox crond -L /dev/stderr

docker-compose logs -f の結果をみると、 cron が複数立ち上がってしまっていました。

app_1  | /usr/lib/python2.7/dist-packages/supervisor/options.py:461: UserWarning: Supervisord is running as root and it is searching for its configuration file in default locations (including its current working directory); you probably want to specify a "-c" argument specifying an absolute path to a configuration file for improved security.
app_1  |   'Supervisord is running as root and it is searching '
app_1  | 2020-04-25 12:11:21,788 CRIT Supervisor is running as root.  Privileges were not dropped because no user is specified in the config file.  If you intend to run as root, you can set user=root in the config file to avoid this message.
app_1  | 2020-04-25 12:11:21,788 INFO Included extra file "/etc/supervisor/conf.d/supervisord.conf" during parsing
app_1  | 2020-04-25 12:11:21,796 INFO RPC interface 'supervisor' initialized
app_1  | 2020-04-25 12:11:21,796 CRIT Server 'unix_http_server' running without any HTTP authentication checking
app_1  | 2020-04-25 12:11:21,796 INFO supervisord started with pid 1
app_1  | 2020-04-25 12:11:22,801 INFO spawned: 'cron' with pid 9
app_1  | 2020-04-25 12:11:22,804 INFO spawned: 'apache2' with pid 10
app_1  | 2020-04-25 12:11:22,807 INFO exited: cron (exit status 0; not expected)
app_1  | 2020-04-25 12:11:23,901 INFO spawned: 'cron' with pid 27
app_1  | 2020-04-25 12:11:23,902 INFO success: apache2 entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
app_1  | 2020-04-25 12:11:23,907 INFO exited: cron (exit status 0; not expected)
app_1  | 2020-04-25 12:11:25,915 INFO spawned: 'cron' with pid 29
app_1  | 2020-04-25 12:11:25,922 INFO exited: cron (exit status 0; not expected)
app_1  | 2020-04-25 12:11:28,934 INFO spawned: 'cron' with pid 31
app_1  | 2020-04-25 12:11:28,941 INFO exited: cron (exit status 0; not expected)
app_1  | 2020-04-25 12:11:29,945 INFO gave up: cron entered FATAL state, too many start retries too quickly

原因は、 cron をバックグランドで立ち上げたことでした。

Supervisor で管理したいプログラムはフォアグランドで動かすと良いようです。

気づいた問題点。 crond の実行ログを docker のログに出力するようにしたと思ったが、出力されていいない。

が、ダメ。

もしかしたら Supervisor が原因かもしれません。後回しにします。

ステップ2. Supervisor で cron も動かす

  • cron は busybox 実現できた diff のみ記します。
$ git diff --cached
diff --git a/Dockerfile b/Dockerfile
index 5b449f6..49966d9 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -23,11 +23,14 @@ RUN a2dissite 000-default \
   && a2ensite 001-my
 ENV APP_ENV laravel
 RUN apt-get update && apt-get install -y \
+  busybox-static \
   supervisor \
   && apt-get clean \
   && rm -rf /var/lib/apt/lists/*
 RUN mkdir -p /var/log/supervisor
 COPY ./docker/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
+COPY ./docker/crontabs/root /var/spool/cron/crontabs/root
+RUN ln -sf /dev/stdout /var/log/cron
 CMD ["/usr/bin/supervisord"]

 FROM composer:1.10.5 AS composer
diff --git a/docker/crontabs/root b/docker/crontabs/root
new file mode 100644
index 0000000..39dd8da
--- /dev/null
+++ b/docker/crontabs/root
@@ -0,0 +1 @@
+* * * * * cd /var/www/html && php artisan schedule:run >> /dev/null 2>&1
diff --git a/docker/supervisord.conf b/docker/supervisord.conf
index 73f0cef..a8662f9 100644
--- a/docker/supervisord.conf
+++ b/docker/supervisord.conf
@@ -3,3 +3,6 @@ nodaemon=true

 [program:apache2]
 command=/usr/local/bin/apache2-foreground
+
+[program:crond]
+command=/bin/busybox crond -f -L /var/log/cron

$

おわりに

ログ出力に問題が残りましたけれども、 1 コンテナ内で Apache と cron を動かすことができました。

以下、他の参考ページです。

以上です。

コメントを残す