docker-composeで起動したコンテナ上でバッチ処理を実行する

docker-composeを利用して起動したコンテナ上のコードを、定期的に実行するバッチ処理についてまとめておきます。

docker-compose.yml を用意する

起動するコンテナは、docker-compose.ymlの内容次第ですが、今回は以下のようにphp-fpmが起動する内容を例にします。

volumesの個所については、適当な内容となっていますので環境に合わせて設定してください。

version: '3'
services:
    nginx:
        image: nginx:1.18
        ports:
            - 80:80
        depends_on:
            - php-fpm
        volumes:
            - /source:/var/www
    php-fpm:
        image: php:7-fpm
        volumes:
            - /source:/var/www

コンテナを起動する

以下のコマンドを実行すると、docker-compose.ymlに記載された「nginx」と「php-fpm」のコンテナが起動します。

docker-compose up -d

コンテナが起動しているか確認する

以下のコマンドを実行すると、コンテナが正常に起動しているかを確認できます。

docker-compose ps

実行後に表示されるコンテナに、「nginx」と「php-fpm」があるか?と言うところと、「State」の個所が「Up」になっていることが確認できれば大丈夫です。

  Name              Command                  State               Ports
-------------------------------------------------------------------------------------------
php-fpm_1   docker-php-entrypoint php-fpm    Up
nginx_1     /docker-entrypoint.sh ngin ...   Up      0.0.0.0:80->80/tcp,:::80->80/tcp

実行する処理

簡易ではありますが、以下のファイル(test.php)をホスト側のディレクトリ(/source)に用意します。
内容としては、現在時刻のタイムスタンプを書き込んだYYYYMMDD.txtと言うファイル名のファイルを作成するだけのものです。

<?php
file_put_contents(date('Ymd').'.txt', time());

php-fpmのコンテナへ入る

下記のコマンドにて、コンテナへ入ることができます。

docker-compose exec php-fpm bash

コンテナへ入った後、対象のディレクトリへ移動します。

cd /var/www

最後に処理を実行しファイルが作成されることを確認します。

php test.php

処理が正常に稼働することが確認できたので、コンテナから出ます。
Windowsの場合には、「Ctrl + P」→「Ctrl + Q」の順番でコンテナから出ることができます。

コンテナが稼働するホストから処理を実行する

コンテナが稼働するホストから処理を実行してみます。
以下のコマンドを実行することで、特定のコンテナにてコマンドを実行されます。

docker-compose exec php-fpm php /var/www/test.php

このコマンドの内容としては以下の通りです。

docker-compose exec [コンテナ名] [実行したいコマンド]

今回の内容を当てはめて見ていくと、コンテナ名は「php-fpm」となり、実行したいコマンドは「php /var/www/test.php」となります。

実行された後にYYYYMMDD.txtを確認すると、ファイルに2行のタイムスタンプが書き込まれていることが確認できます。

cronからコマンドを実行する

最後に定期的に処理を実行するために、ホストのcronに設定を行います。
今回は、面倒なのでcrontabから設定します。

* * * * * cd /docker; docker-compose exec php-fpm php /var/www/test.php

設定後にcronのログから処理が呼び出されていることが確認できると思いますが、処理は実行されないはずです。

cronから実行した際に、docker-composeを見つけられない、または「the input device is not a TTY」とTTYに関連したエラーが発生するはずです。

docker-composeを見つけられない場合

docker-composeがあるディレクトリをフルパスで設定します。

* * * * * cd /docker; docker-compose exec /usr/local/bin/php-fpm php /var/www/test.php

the input device is not a TTYが出力される場合

docker-composeのオプションにある「-T」を指定します。

* * * * * cd /docker; docker-compose exec -T php-fpm php /var/www/test.php

まとめ

コンテナの起動からホストからの処理の起動までを試してみました。


コンテナにcronを入れて動かす方法や、cronでコンテナを起動する方法もあると思いますが、準備などを考えた際に今回紹介した方法は定期的な処理を動かす手段としては、設定も少なく楽な内容ではないでしょうか。

関連する記事