【Docker】CakePHPをcronで定時処理する方法




今回はDocker環境に構築したCakePHPアプリを、cronで定時処理する手順について紹介したいと思います。

例えば、データベースのバックアップをしたり、常時更新されているデータベースを特定の時刻でスナップショットするなど活用できるかと思います。

Docker環境

  • php-fpm(今回はcronをここで実行します)
  • mysql 5.6
  • nginx
  • cakephp3

1. CakePHP3でShellとTaskを生成

まずはCakePHP3で具体的な処理を書いていきます。今回はApp名をAppNameと仮定してパスを記述していきます。こちらのサイトでとてもわかり易く詳細に書かれているので、もしうまく行かない箇所があれば参照いただければと思います。(僕もこちらを参考にやりました)

Shellの作成

Shellとは、コマンドラインからCakePHPを実行するための機能です。まずはShellファイルを作成します。

#phpfpmのコンテナに入る
docker exec -it [phpfpmのコンテナ名] /bin/sh

# AppName/binに移動
cd AppName/bin

#shellファイルを作成 => AppName/src/Shell/に生成されます
./cake bake shell Test

結果

Creating file /var/www/html/AppName/src/Shell/TestShell.php
Wrote `/var/www/html/AppName/src/Shell/TestShell.php`

Baking test case for App\Shell\TestShell ...

Creating file /var/www/html/AppName/tests/TestCase/Shell/TestShellTest.php
Wrote `/var/www/html/AppName/tests/TestCase/Shell/TestShellTest.php`

Taskの作成

Taskとは、実際に処理を行う部分のことです。そうですね、Shellが命令する側でTaskが実際に動く側というイメージでしょうか。基本的に、ShellからTaskに書かれた処理を実行します。

#phpfpmのコンテナに入る
docker exec -it [phpfpmのコンテナ名] /bin/sh

# AppName/bin に移動
cd AppName/bin 

# Taskを作成 => AppName/src/Shell/Task/ に生成
./cake bake task Hoge

結果

Creating file /var/www/html/AppName/src/Shell/Task/HogeTask.php
Wrote `/var/www/html/AppName/src/Shell/Task/HogeTask.php`

Baking test case for App\Shell\Task\HogeTask ...

Creating file /var/www/html/AppName/tests/TestCase/Shell/Task/HogeTaskTest.php
Wrote `/var/www/html/AppName/tests/TestCase/Shell/Task/HogeTaskTest.php`

2. Taskを書く

AppName/src/Shell/Task/HogeTask.phpを開き、main()以下に独自のメソッドを書いていきます。

  1. HogeFunc()メソッドを書く
  2. main()の中でHogeFunc()を実行する
<?php
namespace App\Shell\Task;

use Cake\Console\Shell;

/**
 * Hoge shell task.
 */
class HogeTask extends Shell
{

    /**
     * Manage the available sub-commands along with their arguments and help
     *
     * @see http://book.cakephp.org/3.0/en/console-and-shells.html#configuring-options-and-generating-help
     * @return \Cake\Console\ConsoleOptionParser
     */
    public function getOptionParser()
    {
        $parser = parent::getOptionParser();

        return $parser;
    }

    /**
     * main() method.
     *
     * @return bool|int|null Success or error code.
     */
    public function main()
    {
      $this->HogeFunc();
    }


    private function HogeFunc()
    {
      return 'aho';
    }
}

Taskの設定はここまででOKです。次にShellから今書いたTaskを実行します。

3. Shellを書く

AppName/src/Shell/TestShell.phpを開きます。

  1. $tasksというクラス変数に、Taskを登録
  2. main()メソッドで処理を実行
<?php
namespace App\Shell;

use Cake\Console\Shell;

/**
 * Test shell command.
 */
class TestShell extends Shell
{
    $tasks = ['Hoge']; //1の処理

    /**
     * Manage the available sub-commands along with their arguments and help
     *
     * @see http://book.cakephp.org/3.0/en/console-and-shells.html#configuring-options-and-generating-help
     *
     * @return \Cake\Console\ConsoleOptionParser
     */
    public function getOptionParser()
    {
        $parser = parent::getOptionParser();

        return $parser;
    }

    /**
     * main() method.
     *
     * @return bool|int|null Success or error code.
     */
    public function main()
    {
        $this->Hoge->main(); //2の処理
        $this->out($this->OptionParser->help());
    }
}

4. 実行してみる

一旦、ここまで書いた処理に不具合がないか手動で確認します。手動でShellを実行するには以下のコマンドを打ちます。

# AppName/bin で
./cake Test

5. cronに定時処理の登録をする

4.がうまく行った場合、phpfpmのcrondに定時処理を登録すればOKです。

# phpfpmのコンテナに入る
docker exec -it [phpfpmのコンテナ名] /bin/sh

# crontabを開く
crontab -e

#デフォルトで5行くらい書かれているので、6行目にcron処理を追記する
*/1 * * * * /var/www/html/AppName/bin/./cake Test

ここまでうまく行けば動くはずです。cronには相対パスではなく常に絶対パスを書かないと動かないようですのでご注意ください。