# Cronジョブの設定と管理

Source: https://support.kapsulehost.com/ja-jp/cron-jobs

cronジョブは、コマンドをスケジュールに従ってバックグラウンドで実行します。サイトに誰かが訪問しているかどうかに関係なく動作します。このガイドでは、KPanelでジョブを追加する方法、このプラットフォーム向けにスケジュールとコマンドを正しく記述する方法、WordPressの信頼性に欠ける標準スケジューラーを置き換える方法、そして期待通りに動作しないときに出力を見つける方法を説明します。

## cronジョブとは、KPanel内での場所

cronはサイトに属するため、メインメニューではなくサイトからアクセスします。

1. [KPanel](https://kpanel.kapsulehost.com)にサインインし、左サイドバーの**ウェブサイト**をクリックします。
2. 目的のサイトをクリックします。
3. サイト自体のメニューで**設定**を開き、次に**Cron**を開きます。

直接のアドレスは`/websites/<site-id>/cron`です。既存のジョブの一覧表が表示されるか、サイトにジョブがない場合は空の状態が表示されます。

![KPanel内のあるサイトのCronページ。そのサイトのスケジュールされたジョブを一覧表示している](https://support.kapsulehost.com/help/screenshots/cron-jobs.13aef775.webp)

## ジョブの追加

右上の**クロンジョブを追加**をクリックします。フォームには3つの項目があります。

### スケジュール

6つのプリセットボタンが式を自動入力してくれます。

| ボタン | 式 |
|---|---|
| 毎分 | `* * * * *` |
| 5 分ごと | `*/5 * * * *` |
| 1 時間ごと | `0 * * * *` |
| 毎日午前 2 時 | `0 2 * * *` |
| 毎週日曜日 | `0 2 * * 0` |
| 毎月1日 | `0 2 1 * *` |

または、**Cron 式**に独自の式を入力します。5つの項目は順に、分、時、日、月、曜日です。

```
minute  hour  day-of-month  month  day-of-week
```

- `0 3 * * *`は毎日午前3時に実行されます。
- `*/15 * * * *`は15分ごとに実行されます。
- `0 9 * * 1`は毎週月曜日の午前9時に実行されます。
- `30 1 1 * *`は毎月1日の午前1時30分に実行されます。
- `0 */6 * * *`は6時間ごとに、正時に実行されます。

### ラベル

後で見分けられるような名前、例えば`WordPress cron`や`Nightly stock sync`などです。これはジョブの一覧表に表示されるものなので、わかりやすい名前にしてください。`job 3`では午前2時に見ても誰の役にも立ちません。

### コマンド

実行するシェルコマンドです。**Save**をクリックしてジョブを作成します。

> **Warning:** フルパスを使用してください。cronは最小限の環境で実行され、シェルプロファイルは一切読み込まれません。そのため、SSHでログインしているときは動作する裸の`php`や相対ディレクトリでも、ここでは何のエラーも出さずに失敗します。毎回パス全体を書き出してください。

## コマンドの書き方

ジョブはサイト自体のシステムユーザーとして実行されるため、ホームディレクトリが正しい基準点となり、`~`は正しく解決されます。サイトのファイルは以下の場所にあります。

```
~/htdocs/yourdomain.co.nz
```

正確なパスは、サイトの**設定**から**SFTP**タブを開くと、**サイトファイル**の下に表示され確認できます。

典型的なコマンドの例です。

```
cd ~/htdocs/yourdomain.co.nz && /usr/bin/wp cron event run --due-now
```

```
cd ~/htdocs/yourdomain.co.nz && /usr/bin/php bin/send-queued-emails.php
```

```
/usr/bin/curl -fsS https://yourdomain.co.nz/api/nightly-report
```

> **Tip:** スケジュールする前にコマンドをテストしてください。`wp`コマンドであれば、サイトの**WordPress**から**Console**セクションに貼り付けて試すか、SSH経由で実行してください。動作しないジョブは、午前3時にログファイルで見つけるよりも、プロンプト上で見つけるほうがはるかに簡単です。

## WordPressの標準スケジューラーの置き換え

WordPressには独自の疑似スケジューラーであるWP-Cronが付属していますが、これは誰かがページを読み込んだときにしか発火しません。訪問の少ないサイトでは、予約投稿が遅れて公開されたり、メールが送信されずに溜まったりします。訪問の多いサイトでは、すべての訪問者がスケジュール確認のコストを負担することになります。

本物のcronジョブはこの両方を解決します。KPanelでは、この切り替えをすべて代行してくれます。

1. サイトを開き、**WordPress**タブを開きます。
2. **WP-Cron**セクションを開きます。
3. **システムcronを有効化**をクリックします。

これにより、WP-Cronを5分ごとに実行するスケジュールが追加され、`DISABLE_WP_CRON`が設定されて、ページの読み込みによってもトリガーされなくなります。同じ画面の**システムcronを削除**は、この両方を元に戻します。

手動で行いたい場合は、2つの手順になります。

**訪問者トリガー版を無効化します。** **設定**から**ファイルマネージャー**を使い、`/* That's all, stop editing! */`の行の上の`wp-config.php`に以下を追加します。

```php
define( 'DISABLE_WP_CRON', true );
```

**本物のジョブを追加します。** **設定**から**Cron**で以下のように設定します。

- スケジュール: `*/5 * * * *`
- ラベル: `WordPress cron`
- コマンド: `cd ~/htdocs/yourdomain.co.nz && /usr/bin/wp cron event run --due-now`

> **Warning:** `DISABLE_WP_CRON`の半分を省略しないでください。両方が動作していると、すべての予約タスクが二重に発火する可能性があります。メールの重複、注文処理の重複、サブスクリプションプラグインでの二重課金などです。WP-Cronセクションのワンクリック操作を使えば、こうしたことは起こりません。

## WooCommerceとバックグラウンドキュー

WooCommerceは、注文ステータスの変更、サブスクリプションの更新、メール、在庫更新のためにバックグラウンドキューを使用します。これはWP-Cronに依存しているため、訪問の少ないショップで不調をきたすまさにその種の処理です。

本物のスケジュールが導入されると、キューは5分ごとに処理されます。wp-admin内の**WooCommerce**から**Status**、**Scheduled Actions**で確認できます。

高トラフィックのショップは`*/2 * * * *`に移行できます。それより短くしてもあまり効果はありません。処理を始めること自体に多くの時間を費やすことになるためです。[WooCommerceの設定](https://support.kapsulehost.com/ja-jp/wordpress-woocommerce)を参照してください。

## 既存ジョブの管理

ジョブの一覧表には**Label**、**Schedule**、**Command**、**最終実行**、**Status**が表示され、各行に2つの操作があります。

- **Disable**はジョブを削除せずに一時停止します。これを押すと**Enable**に変わり、再開できます。ジョブが問題を引き起こしているかどうかをテストする際に使用します。
- **Delete**は完全に削除します。確認を求められ、スケジュールされた実行は即座に停止します。

> **Important:** cronジョブの削除は元に戻せません。スケジュールはその場でサーバーから削除されます。一時的に止めたいだけの場合は、**Disable**を使用してください。

## 出力の確認方法

KapsuleHostが作成するすべてのジョブは、出力を自動的に記録します。標準出力とエラーは、サイトユーザーのホームディレクトリ内の`cron-logs`ディレクトリにあるログファイルに追記されます。ジョブごとに1つのファイルです。

このログは「ジョブは実行されたのか?」というほぼすべての疑問に対する答えです。コマンドが出力した内容と、発生したエラーが記録されているからです。

それを読むには、SSH経由で接続し、`~/cron-logs/`を確認してください。SSHは鍵認証を使用するため、まずサイトの**設定**から**SSH キー**タブで公開鍵を追加してください。詳しくは[SSHキーの追加](https://support.kapsulehost.com/ja-jp/adding-ssh-keys)を参照してください。

> **Note:** ファイルマネージャーとSFTPアカウントは、サイトディレクトリ`~/htdocs/yourdomain.co.nz`内に限定されており、`cron-logs`はその1つ上の階層にあります。これは意図的な設計です。SFTPアクセス権を持つ外部の請負業者が、ウェブサイト以外の場所に触れないようにするためです。ログにアクセスするにはネイティブのSSHを使用するか、以下のようにサイトディレクトリへ出力をリダイレクトしてください。

ファイルマネージャーで開ける場所に出力を置きたい場合は、自分でリダイレクトしてください。

```
cd ~/htdocs/yourdomain.co.nz && /usr/bin/wp cron event run --due-now >> ~/htdocs/yourdomain.co.nz/wp-content/cron.log 2>&1
```

`2>&1`は、エラーを通常出力と同じファイルに送ります。これを付けないと、エラーはどこにも記録されません。

> **Warning:** サイトディレクトリ内のものは、理論上ウェブ経由でリクエストされる可能性があります。リダイレクトしたログはサイトのルートではなく`wp-content`の下に置き、誰にも推測できないファイル名を付け、デバッグが終わったら削除してください。

## 良い実践方法

- **スケジュールを分散させましょう。** 6つのジョブをすべて`0 2 * * *`に設定すると、すべて同時に開始してしまいます。`0 2`、`10 2`、`20 2`のように分散させてください。
- **本当に必要でない限り、毎分実行は使わないでください。** WordPressやWooCommerceを含め、ほとんどの場合`*/5`で十分です。
- **ジョブは短くしてください。** 実行間隔より長くかかるジョブは、次の実行と重なってしまいます。
- **出力が多いジョブはリダイレクトしてください。** そうすることで、おしゃべりなジョブがディスクを埋め尽くすことを防げます。
- **時々一覧を見直してください。** 削除したプラグインから残されたジョブが動き続けていることがあります。

## トラブルシューティング

**ジョブがまったく実行されないようです。** まずパスを確認してください。ログファイルを開いてください。次にステータスが**Disabled**ではなく**Active**であることを確認してください。それから同じコマンドをSSH経由で実行し、何が表示されるか確認してください。

**ログに「command not found」と表示される。** フルパスが欠けています。裸の名前ではなく、`/usr/bin/php`、`/usr/bin/wp`、`/usr/bin/curl`のように指定してください。

**Permission denied。** ジョブはサイトのシステムユーザーとして実行されます。そのユーザーは、コマンドが触れるすべてのものを所有しているか、少なくとも読み取れる必要があります。権限については[ファイルマネージャーの使用](https://support.kapsulehost.com/ja-jp/file-manager)を参照してください。

**WordPressのタスクが依然として遅れて実行される。** 切り替えの両方が完了しているか確認してください。**設定**から**Cron**にスケジュールが存在すること、そして`DISABLE_WP_CRON`が設定されていることです。**WordPress**タブの**WP-Cron**セクションで、両方の現在の状態を確認できます。

**ジョブは実行されるが、その間サイトが重くなる。** 比較的空いている時間帯に移すか、作業をより小さなバッチに分割してください。サイトレベルのリソース使用状況は**パフォーマンス**で確認できます。[ウェブサイトの速度改善](https://support.kapsulehost.com/ja-jp/website-speed)を参照してください。

**プラグインの更新後にジョブが動かなくなった。** コマンドのパスが変わった可能性があります。ログを確認し、古いジョブを削除して修正したジョブを新たに追加することで、一覧表のコマンドを更新してください。
