スマートフォン・タブレットからインターネットサーバーオペレーション

APPW.jp
 

APPW.jp  /  WordPress

予約投稿 失敗時の対処手順

WP-Cron 無効化 & サーバー cron による確実なスケジュール実行 · WP-CLI インストール & マルチサイト対応

// 01 — background

予約投稿が失敗する背景と原因

WordPress の予約投稿は内部の疑似 cron 機構「WP-Cron」に依存しています。WP-Cron はサイトへのアクセスをトリガーに動作するため、アクセスが少ないサイトや低スペック VPS では予約時刻を過ぎても投稿されない問題が頻発します。

⚠️

WP-Cron はページリクエストに「便乗」して実行される擬似タスクキューです。アクセスが無い時間帯には一切実行されないため、深夜・早朝の予約投稿で特に失敗しやすくなります。

WP-Cron が担う主な処理

wp-cron.php は予約投稿だけでなく、以下の処理も担っています。WP-Cron を完全に止める場合はサーバー cron で代替する必要があります。

📝 予約投稿
の公開
🔄 プラグイン・
テーマ更新確認
🗑️ 削除済み
コメントの整理
💾 バックアップ
プラグインの実行
💡

対処の基本方針は「WP-Cron(擬似)を無効化し、OS の cron(本物)で wp-cron.php を定期実行する」ことです。これにより、アクセス有無に関わらず確実にスケジュール処理が動きます。

// 02 — steps

対処手順

1
wp-config.php で WP-Cron を無効化する

WordPress が自動で wp-cron.php を呼び出すのを止めます。wp-config.php の「編集が必要なのはここまでです!」の行の直前に以下の1行を追記してください。

wp-config.php
// WordPress の疑似 cron を無効化する(サーバー cron で代替するため)
define('DISABLE_WP_CRON', true);

/* 編集が必要なのはここまでです!WordPress でブログをお楽しみください。 */
📌

DISABLE_WP_CRONtrue にすると、WordPress はページ読み込み時に wp-cron.php への内部リクエストを送らなくなります。これにより不要なオーバーヘッドも削減できます。

2
Scheduled Post Trigger プラグインをインストールする(任意)

サーバー cron の設定が難しい環境や、手軽に試したい場合の代替手段です。Scheduled Post Trigger は、訪問者がサイトを閲覧したタイミングで予約済み投稿を自動公開するプラグインです。

アクセスに依存する点は WP-Cron と同様ですが、深夜や早朝でも定期的にアクセスがあるサイトなら有効です。アクセスが少ないサイトの場合はステップ 3(サーバー cron)の設定を推奨します。

⚠️

プラグインによる対処とサーバー cron による対処は、どちらか一方を選択してください。両方同時に設定する必要はありません。確実性を優先するならサーバー cron が推奨です。

3
サーバーの cron で wp-cron.php を定期実行する

OS の cron デーモンから直接 wp-cron.php を呼び出す方法です。アクセスに依存しないため最も確実です。以下のコマンドで crontab を編集します。

shell
# root の crontab を編集(sudo で実行)
sudo crontab -e
shell
ユーザ名の crontab を編集(ユーザ名で実行)
sudo crontab -u ユーザ名 -e

エディタが開いたら、以下の行を追記します。/path/to/WordPress は実際の WordPress インストールパスに変更してください。

crontab
# 5分おきに wp-cron.php を実行する
*/5 * * * * cd /path/to/WordPress; /usr/bin/php wp-cron.php >/dev/null 2>&1
📌

>/dev/null 2>&1 は標準出力と標準エラー出力をすべて破棄する指定です。これにより wp-cron.php の実行結果がメールで届くのを防ぎます。実行状況を確認したい場合は後述の syslog で確認できます。

💡

実行間隔は 5分おき(*/5 が一般的です。予約投稿の精度(最大5分のズレ)と VPS への負荷のバランスが取れています。頻度を上げる場合は */1(毎分)も可能ですが、低スペック VPS では負荷に注意してください。

// 03 — cron syntax

cron の構文リファレンス

crontab の書式は 「分 時 日 月 曜日 コマンド」 の5フィールドです。各フィールドを * にすると「すべて」を意味します。

書式
分(0-59)  時(0-23)  日(1-31)  月(1-12)  曜日(0-6)  コマンド

曜日の数値:  0=日曜  1=月曜  2=火曜  3=水曜  4=木曜  5=金曜  6=土曜

フィールドの特殊記法

記法意味説明
* すべて * * * * * 毎分実行
*/n n 毎 */5 * * * * 5分おきに実行
*/n(時) n 時間毎 0 */2 * * * 2時間おきの0分に実行
n 指定値 30 3 * * * 毎日 3:30 に実行
n-m 範囲指定 0 9-17 * * * 9時〜17時の毎時0分に実行
a,b,c 列挙(OR) 0 8,12,18 * * * 8時・12時・18時の0分に実行
曜日指定 特定曜日 0 9 * * 1-5 平日(月〜金)の 9:00 に実行

wp-cron.php 向け設定例

crontab 設定例
# 5分おき(推奨・一般的な設定)
*/5 * * * *  cd /var/www/html/wordpress; /usr/bin/php wp-cron.php >/dev/null 2>&1

# 毎分(最大精度・低スペック VPS では注意)
* * * * *    cd /var/www/html/wordpress; /usr/bin/php wp-cron.php >/dev/null 2>&1

# 毎時0分(更新頻度が低いサイト向け)
0 * * * *    cd /var/www/html/wordpress; /usr/bin/php wp-cron.php >/dev/null 2>&1

# 平日 9時〜21時の間、10分おき(営業時間帯に絞る例)
*/10 9-21 * * 1-5  cd /var/www/html/wordpress; /usr/bin/php wp-cron.php >/dev/null 2>&1

// 04 — management commands

crontab 管理コマンド

📋  設定の確認
sudo crontab -l

現在登録されている cron ジョブの一覧を表示します。設定後は必ずこのコマンドで内容を確認してください。

✏️  設定の編集
sudo crontab -e

エディタで crontab を編集します。デフォルトエディタが nano の場合、保存は Ctrl+OEnterCtrl+X です。

🗑️  設定の全削除
sudo crontab -r

root の crontab をすべて削除します。元に戻せないため注意が必要です。削除前に -l でバックアップを取っておくことを推奨します。

📊  実行ログの確認
sudo grep CRON /var/log/syslog

syslog から cron の実行履歴を抽出します。正常に実行されているか、エラーが発生していないかを確認できます。

ログの確認例

実行例
# 直近の CRON ログを20行表示
sudo grep CRON /var/log/syslog | tail -20

# wp-cron に関するログだけ絞り込む
sudo grep CRON /var/log/syslog | grep wp-cron

# リアルタイムで CRON ログを監視する(Ctrl+C で終了)
sudo tail -f /var/log/syslog | grep CRON
💡

Ubuntu 系では /var/log/syslog、CentOS / RHEL 系では /var/log/cron にログが出力されます。ログに CMD と表示されていれば cron は正常に実行されています。

PHP のパスが異なる場合

crontab 内の /usr/bin/php は環境によって異なる場合があります。以下のコマンドで PHP の実パスを確認してください。

shell
# PHP の実行パスを確認する
which php

# 出力例: /usr/bin/php  または  /usr/local/bin/php

// 05 — WP-CLI installation

WP-CLI のインストール

WP-CLI(WordPress Command Line Interface)は WordPress をコマンドラインから操作するための公式ツールです。マルチサイトの cron をサイト横断で管理する場合に特に有用です。

💡

WP-CLI の動作要件は PHP 7.2.24 以上です。php -v でバージョンを確認してから進めてください。

① phar ファイルのダウンロード

公式推奨のインストール方法は phar(PHP Archive)ビルドを取得する方法です。

shell
# wp-cli.phar をダウンロード(curl または wget)
curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar

# ダウンロードできたか確認
php wp-cli.phar --info

② 実行権限の付与とパスへの配置

wp とだけ入力して実行できるよう、実行権限を付与して PATH の通ったディレクトリに移動します。

shell
# 実行権限を付与
chmod +x wp-cli.phar

# /usr/local/bin/wp として配置(グローバルに使えるようにする)
sudo mv wp-cli.phar /usr/local/bin/wp

③ インストール確認

shell
wp --info

正常にインストールされると以下のような情報が表示されます。

出力例
OS:      Linux 6.8.0-57-generic x86_64
Shell:   /bin/bash
PHP binary:    /usr/bin/php
PHP version:   8.3.6
WP-CLI root dir: phar://wp-cli.phar/vendor/wp-cli/wp-cli
WP-CLI version: 2.11.0

WP-CLI のアップデート

shell
# 最新版へアップデート
sudo wp cli update

# バージョン確認
wp cli version
📌

WP-CLI コマンドは WordPress のインストールディレクトリ内で実行する必要があります。別ディレクトリから実行する場合は --path=/var/www/html/wordpress オプションで WordPress のパスを指定してください。

// 06 — multisite

マルチサイトの場合の対処(WP-CLI ループ)

WordPress マルチサイトでは、WP-Cron は各サブサイトで独立して動作します。メインサイトの wp-cron.php を実行してもメインサイトの cron しか処理されず、サブサイトの予約投稿は公開されません。

⚠️

マルチサイト構成では、シングルサイト向けの wp-cron.php 直接実行(セクション 02 ステップ3)はメインサイトにしか効きません。サブサイトの予約投稿を確実に処理するには以下の方法を使用してください。

wp-config.php の設定(共通)

マルチサイトでも DISABLE_WP_CRON の設定は1箇所の追記でネットワーク全体に適用されます。セクション 02 ステップ1 と同じ設定です。

wp-config.php
define('DISABLE_WP_CRON', true);
/* 編集が必要なのはここまでです!WordPress でブログをお楽しみください。 */

アプローチ① WP-CLI でメインサイトのみ実行

サブサイトが1〜2個程度の小規模ネットワーク向けの方法です。サイトごとに --url を指定して個別に実行します。

crontab
# メインサイト
*/5 * * * * cd /var/www/html/wordpress && /usr/local/bin/wp cron event run --due-now --url=https://example.com --allow-root >/dev/null 2>&1

# サブサイト(サブドメイン型)
*/5 * * * * cd /var/www/html/wordpress && /usr/local/bin/wp cron event run --due-now --url=https://sub.example.com --allow-root >/dev/null 2>&1

# サブサイト(サブディレクトリ型)
*/5 * * * * cd /var/www/html/wordpress && /usr/local/bin/wp cron event run --due-now --url=https://example.com/sub --allow-root >/dev/null 2>&1

アプローチ② WP-CLI で全サブサイトをループ実行(推奨)

サブサイト数が多いネットワーク向けの推奨方法です。wp site list でネットワーク内の全サイトURLを取得し、xargs でループして cron を実行します。

crontab
# 全サブサイトを横断して cron を実行(15分おき推奨)
*/15 * * * * cd /var/www/html/wordpress && /usr/local/bin/wp site list --field=url --allow-root | /usr/bin/xargs -I \% /usr/local/bin/wp cron event run --due-now --url=\% --allow-root >/dev/null 2>&1
📌

wp site list --field=url はネットワーク内の全サイトURLを1行ずつ出力します。xargs -I % はその各URLを % に代入して後続コマンドを繰り返し実行します。サイト数が多い場合は間隔を */15 以上に広げてサーバー負荷を抑えてください。

多重実行防止(flock)を加えた安全な設定

前の cron 実行が終わる前に次の実行が始まる「多重起動」を防ぐには flock コマンドを組み合わせます。

crontab
# flock でロックを取得し、多重実行を防止する
*/5 * * * * cd /var/www/html/wordpress; /usr/bin/flock -n /tmp/wp_cron.lock /usr/local/bin/wp cron event run --due-now --quiet --allow-root
💡

flock -n はロックファイルが取得できない場合(前の実行が進行中)はスキップします。これにより VPS のメモリ・CPU を使い果たすリスクを軽減できます。

WP-CLI で cron の状態を確認・デバッグする

📋  cron イベント一覧
wp cron event list \
  --url=https://example.com

指定サイトのスケジュール済みイベントを一覧表示します。next_run が過去の場合は滞留しています。

▶️  期限切れ cron を手動実行
wp cron event run --due-now \
  --url=https://example.com

実行時刻を過ぎた全イベントを即時実行します。デバッグ時に有効です。

🔍  全サイトのイベント確認
wp site list --field=url \
  --allow-root | \
xargs -I % wp cron event list \
  --url=% --allow-root

ネットワーク内の全サイトのcronイベントを横断確認します。

🧹  スケジュール済みイベント削除
wp cron event delete \
  <hook名> \
  --url=https://example.com

特定フックのイベントを削除します。プラグイン削除後に残った孤立cronの掃除に使います。

マルチサイト対応まとめ

サブサイト数推奨アプローチcrontab 間隔
2〜3個 アプローチ①:URLを個別指定 */5
10個程度まで アプローチ②:WP-CLI xargs ループ */15
多数・高負荷 アプローチ②+flock で多重実行防止 */15 以上

『WordPress 予約投稿 失敗時の対処手順 / WP-CLI』を公開しました。