トラブルシューティング · Laravel
Laravel スケジューラーが動かない?サイレント障害の修正
Laravel のスケジューラーがサイレントに停止する理由 — cron エントリの欠落、間違ったユーザー、環境、重複タスク — とその修正方法。
Laravel のスケジューラーは1つのシステム cron エントリで駆動されます。そのエントリが間違っているか、その下の環境が間違っていると、すべてのスケジュールされたタスクがサイレントに停止します。チェックリストはこちらです。
1. 1つの cron エントリが存在しなければならない
Laravel には毎分 schedule:run を呼び出す crontab の行が1つだけ必要です。正しいユーザー(通常デプロイユーザー、root ではない)に設定されていることを確認します。
crontab -l
次のように記述されているはずです。
* * * * * cd /var/www/app && php artisan schedule:run >> /dev/null 2>&1
ない場合は crontab -e で追加します。よくあるデプロイの間違いは、アプリが www-data で動いているのに root として追加すること(またはその逆)です。
2. 正しい PHP バイナリと絶対パスを使う
cron では php が解決しないか、間違ったバージョンになる可能性があります。フルパスとプロジェクトのパスを使ってください。
* * * * * cd /var/www/app && /usr/bin/php8.3 artisan schedule:run >> /dev/null 2>&1
3. 環境がシェルと異なる
cron はシェルプロファイルを読み込まないため、そこで設定したものはすべて存在しません。Laravel は .env を読み込むので問題ありませんが、タスクが他のバイナリをシェルアウトする場合は明示的に PATH を指定してください。また APP_ENV とキュー/キャッシュの設定が本番と一致していることを確認してください。
4. 出力をサイレンスにしてデバッグできない
>> /dev/null 2>&1 はエラーを含むすべてを隠します。一時的にログに記録してください。
* * * * * cd /var/www/app && php artisan schedule:run >> storage/logs/schedule.log 2>&1
次に php artisan schedule:run を手動で実行して出力を確認します — ほとんどの失敗(権限、環境の欠落、DB 接続)はすぐに現れます。
5. タスクが重複またはハングする
毎分実行する長いタスクが積み重なる可能性があります。遅い実行が次をブロックしないよう Laravel のガードを使ってください。
$schedule->command('reports:build')
->hourly()
->withoutOverlapping()
->onOneServer();
本当の問題: スケジューラーは停止してもサイレントのまま
schedule:run の発火が停止した場合 — サーバーが再起動した、crontab がデプロイで消えた、PHP がアップグレードされた — Laravel にはあなたに伝える方法がありません。キューに入ったレポートやメールは単純に停止します。
スケジューラー自体が生きていることを確認するため、スケジュールされたタスクからハートビートを ping してください。
$schedule->call(function () {
Http::timeout(10)->get('https://ping.steadycron.com/<your-ping-token>');
})->everyFifteenMinutes();
その ping が欠落すると、SteadyCron がアラートを送ります — スケジューラーがダウンしていることを、ユーザーが気づく前に知ることができます。