Concrete CMS タスク設定方法: Cron版  (V9 以降)


Concrete CMS v9 よりバッチ処理をバックグラウンドで行うための新しい「タスク」機能。

今日はそのタスクをきちんと活用するための Cron 設定方法を解説します。

systemd timer を利用した方法も以下で解説しています。

**Concrete CMS タスクの設定方法: systemd timer 版 (V9 以降)**
https://qiita.com/katzueno/items/fe3cd4daed0804e4927f
**Concrete CMS タスク設定方法 (Plesk 編)**
https://qiita.com/katzueno/items/a631af293c89acc5e024

(一気に書き上げていて文章の推敲がまだです。わかりづらいところがあったらご指摘願います。)


# Concrete CMS V9 から搭載された「タスク」とは

Concrete CMS V9 から、sitemap.xml ファイルの生成、検索インデックスの生成などの定期的に起動させるバッチ処理が「自動実行ジョブ」から「タスク」と呼ばれる機能に変わりました。

[Mercure](https://mercure.rocks/)と呼ばれるオープンソースコミュニケーションソリューションを使い、ブラウザでも、サーバーサイドでもリアルタイムにバッチ処理を実行できるソリューションです。

V8 までの Concrete CMS では、サイトの規模が大きくなると、自動実行ジョブを個別に実行させる必要があり、サーバー側の Cron 設定をたくさん行う必要がありました。

しかし V9 からは、サーバーで設定が必要なのは、1~2個の Cron だけ。あとは、Concrete CMS の管理画面で処理を追加していくだけになり、サーバー側の設定の煩わしさを解消しれくれます。

今回は Concrete CMS でのタスク設定を、一般的なレンタルサーバーでも提供されている Cron を使って設定する方法を解説します。


# 1.初期設定

## 1-1. Concrete CMS 管理画面での設定

- 管理画面 -> システムと設定 -> 自動化 -> 自動化設定 ページに訪問
	- [Concrete URL]/index.php/dashboard/system/automation/settings
- `キューを確認する` を `手動` に変更
	- `自動`で設定している場合は、ユーザーが Concrete CMS にアクセスした際にユーザーの訪問によってタスクが実行されます。アクセスが少ない場合はタスクの完了が遅れてしまう場合があります。
- (オプション) `ログ` を保存したければ、ログ保存先をサーバー上に作成、そして「ログ」の設定を`無効` から `ファイル` に変更し、`Log Directory` に、サーバーパスを入力 (**root権限のあるサーバー向け**)
	- 例: `/var/log/ccm-task` で設定する場合
		- `sudo mkdir /var/log/ccm-task`
		- `sudo chown 【nginx:nginx, apache:apache, もしくはSSHユーザー】 /var/log/ccm-task`
		- `sudo chmod 755 /var/log/ccm-task`
		- ログは肥大化するので、logrotate を有効にしよう (STEP 7 参照　)
- `スケジューラー` を `有効` に変更
- 保存


## 1-2. タスクスケジューラーの Cron を設定

スケジューラーを毎分起動します。
このスケジューラー cron を毎分1回起動させることで、日時予約しているタスクを起動します。

### 実行コマンド例

レンタルサーバーなどのコントロールパネルで設定する場合、「コマンド」部分は以下の様に記述します。

```
[Concrete CMS までのパス]/concrete/bin/concrete concrete:scheduler:run
```

### crontab での設定例

VPS, 専用, クラウドサーバーで crontab を使って設定する時の例です。

```
* * * * * [Concrete CMS までのパス]/concrete/bin/concrete concrete:scheduler:run
```

*`/etc/crontab`での設定の場合は、実行ユーザーを記述することを忘れずに。


## 1-3. コンシューマーの起動設定（キューを手動で確認する場合）

1-1 で`キューを確認する` を `手動` に変更した場合に必ず設定が必要な cron です。

### 1-3-1. レンタルサーバーで、Cron を実行できる最高時間を調べる

このコンシューマータスクは、可能であればずっと走り続けて欲しいタスクです。

レンタルサーバーによって、Cron で実行できる時間が制限されています。


### 1-3-2. 実行コマンド例

今回、レンタルサーバーが、Cron の実行時間を 1分までと制限していると仮定します。

本来ならは、コンシューマーのジョブは走り続けられるだけ走り続けたいのですが、55秒で停止して毎分起動する様に設定します。

`--time-limie` オプションで、55秒で止めるというコマンドを追加します。


```
[Concrete CMS までのパス]concrete/bin/concrete messenger:consume async --time-limit=55
```

### 1-3-3. crontab での設定例 (毎分の場合)

VPS, 専用, クラウドサーバーで crontab を使って設定する時の例です。

```
* * * * * [Concrete CMS までのパス]concrete/bin/concrete messenger:consume async --time-limit=55
```

- `/etc/crontab`での設定の場合は、実行ユーザーを記述することを忘れずに。

### 1-3-4. crontab での設定例 (1時間おきの場合)

root権限のあるサーバーなどCronでの実効時間に制限がなければ、3590秒≒1時間 など若干長めに設定されることをお勧めします。その際は毎分起動するのではなく、毎時0分に起動するよう設定します。

```
0 * * * * [Concrete CMS までのパス]concrete/bin/concrete messenger:consume async --time-limit=3590
```

# 2 設定 & 確認

実際にタスクをスケジュール設定し、タスクが正常に動くか確認しましょう。

## 2-1 タスクをスケジュールしてみる

sitemap.xml や索引インデックスのタスクを管理画面から設定します。

- 管理画面 -> システムと設定 -> 自動化 -> タスク に訪問
	- `コンクリのトップ/index.php/dashboard/system/automation/tasks`
- スケジュール設定したいタスクを選ぶ
- スクロールダウンし `タスク実行` メニューが表示されます
- `すぐに` か `定期的なタスクをスケジュール` の選択項目の後者を選択します。
- `Cron expression` という Cron 形式で実行時間を指定します。

### 2-2 Cron expression とは

曜日・月・日・時間・分を指定するための式みたいなものです。
アスタリスクをいれると、毎分・毎時間・毎日などと複数回設定できる様になります。

```
分・時・日・月・曜日
```

#### 2-2-1 例: 毎朝8時に実行

```
0  8  *  *  *  *
```

#### 2-2-2 例: 1/1 0:00 に実行

```
0  0  1  1  *  *
```

#### 2-2-3 例: 毎週月曜日 0:00 に実行

```
0  0  *  *  *  1
```

これで、タスクによる Cron 設定を行うことができます。


# 3. Enviroment を使って Concrete CMS の config 環境を変える方法

Concrete CMS には、変数を設定することで、同じコードベースでも、本番・検証・開発の設定(Config)ファイルを用意し、変数に応じて読み込む config を変えることができる機能がついています。

参考: [Concrete CMS で環境ごとに別の設定ファイルを読み込む方法](https://qiita.com/katzueno/items/43258716424aac82468f)

## サーバー側 Cron の設定例

Cron のコマンドの前に bash の変数を設定する定義文とスペースを加えます`CONCRETE5_ENV=[変数名]`。変数を設定した Concrete CMS の環境名に変えてください。

```
* * * * * CONCRETE5_ENV=[変数名] [Concrete CMS までのパス]/concrete/bin/concrete concrete:scheduler:run
* * * * * CONCRETE5_ENV=[変数名] [Concrete CMS までのパス]/concrete/bin/concrete messenger:consume async --time-limit=55
```

例：ENV名 `production` の場合

```
* * * * * CONCRETE5_ENV=production [Concrete CMS までのパス]/concrete/bin/concrete concrete:scheduler:run
* * * * * CONCRETE5_ENV=production [Concrete CMS までのパス]/concrete/bin/concrete messenger:consume async --time-limit=55

```
# 4. PHP のパスを指定する場合 (Plesk, Remi レポ使用時など)

PLESK 環境や Remi の PHP を使って、複数の PHP バージョンを使い分けるような構成のサーバーや、コマンドラインレベルで PHP バイナリのパスが通っていない場合がありました。その場合は、PHP のバイナリパスを指定して、実行する必要があります。

## サーバー側 Cron の設定例

```
* * * * * [PHPバイナリのパス] [Concrete CMS までのパス]/concrete/bin/concrete concrete:scheduler:run
* * * * * [PHPバイナリのパス] [Concrete CMS までのパス]/concrete/bin/concrete messenger:consume async --time-limit=55
```

PHP のバイナリパスはサーバーによって違います。サーバー管理者に問い合わせましょう。例えば PHP バイナリの場所が `/opt/remi/php82/root/usr/bin/php` で、Concrete CMS の場所が `/var/www/vhosts/example.com/htdocs/` だった場合、以下のようになります。

```
* * * * * /opt/remi/php82/root/usr/bin/php /var/www/vhosts/example.com/htdocs/concrete/bin/concrete concrete:scheduler:run
* * * * * /opt/remi/php82/root/usr/bin/php /var/www/vhosts/example.com/htdocs/concrete/bin/concrete messenger:consume async --time-limit=55
```

加えて環境変数 `CONCRETE5_ENV=production` を加えたい場合は以下のようになります。

```
* * * * * CONCRETE5_ENV=production /opt/remi/php82/root/usr/bin/php /var/www/vhosts/example.com/htdocs/concrete/bin/concrete concrete:scheduler:run
* * * * * CONCRETE5_ENV=production /opt/remi/php82/root/usr/bin/php /var/www/vhosts/example.com/htdocs/concrete/bin/concrete messenger:consume async --time-limit=55
```