こんにちは、AIシステムズです。
この記事は、代表コバが現場で蓄積してきたサーバー運用の知見をもとに、AIを活用して構成・執筆し、弊社にて最終チェックを行ったものです。
cronジョブを「毎朝3時に動かしたい」と設定したのに、実際にはまったく別の時刻に動いている、あるいは動いた形跡すらない——中小企業のサーバー保守の現場で、私たちが何度も遭遇してきたトラブルです。原因の大半はタイムゾーン設定のズレか、cronが実行するコマンドの環境変数の違いに集約されます。
- cronジョブが指定時間にズレて動く本当の原因
- システムTZ・cronデーモン・ジョブ単位TZの3階層の見方
- 実際に弊社が現場で使っている確認・修正コマンド
- WordPressのwp-cronと混同しがちな落とし穴
- 再発を防ぐためのチェックリスト
目次
- cronがズレる主要な原因
- タイムゾーンを3階層で確認する
- 実際の修正手順
- WordPressのwp-cronとシステムcronの違い
- こういう企業に向いている/向いていない
- 再発防止チェックリスト
cronがズレる主要な原因
弊社が中小企業のサーバー保守で対応してきた案件では、cronジョブが指定時間に動かない原因は次の3つにほぼ集約されます。
- サーバーのシステムタイムゾーンがUTCのままになっており、JSTで書いた時刻が9時間ズレて解釈されている
- cronから起動されたシェルで環境変数(PATH・LANG・TZ)がログイン時と異なるため、スクリプト内部でエラーになっている
- root権限のcrontabと一般ユーザーのcrontabを混同して、想定したジョブが登録されていない
たとえば、レンタルサーバーから自社管理のVPSに移行した直後の案件では、OSのデフォルトがUTCのままで、「深夜バッチ」を3:00と書いたのに日本時間12:00に走ってしまい、業務時間中に重い処理が走るという事故が起きていました。
タイムゾーンを3階層で確認する
タイムゾーンは「サーバー全体」「cronデーモン」「ジョブ単位」の3つで個別に決まります。1か所だけ直しても再発するのがこの問題の厄介なところです。
1. システム全体のタイムゾーン
timedatectl
出力の Time zone 行を確認します。Asia/Tokyo (JST, +0900) になっていなければ、まずここを直します。
sudo timedatectl set-timezone Asia/Tokyo
2. cronデーモンが認識しているタイムゾーン
ディストリビューションによっては、cronデーモン自体が独自にTZを持っている場合があります。systemd配下のcronなら、再起動でシステムTZを取り直します。
sudo systemctl restart crond # RHEL/AlmaLinux/Rocky系
sudo systemctl restart cron # Debian/Ubuntu系
これを忘れると、システムTZを直したのにcronだけ古いTZのまま動き続けます。
3. ジョブ単位のタイムゾーン
crontabの先頭に CRON_TZ を書くと、そのcrontab内のジョブだけ別TZで動かせます。意図せず指定されているケースもあるので、現状を必ず確認します。
CRON_TZ=Asia/Tokyo
0 3 * * * /usr/local/bin/nightly-batch.sh
実際の修正手順
弊社が現場で使っている確認・修正の順序は次のとおりです。
timedatectlでシステムTZを確認・修正sudo crontab -lとcrontab -l(一般ユーザー)の両方で、想定したジョブが登録されているか確認/var/log/cron(RHEL系)または/var/log/syslog(Debian系)で実行ログを追う- ジョブ内のスクリプトを
/bin/sh -c "..."でcronと同じ最小環境から手動実行し、PATHやLANGの差で落ちていないか確認 - cronデーモンを再起動して反映
ログを見ずに勘で直そうとすると、原因が複合していたときに必ず再発します。最初の30分はログの読み込みに使ったほうが、結果的に短時間で解決します。
WordPressのwp-cronとシステムcronの違い
WordPressサイトの保守で混乱しやすいのが、wp-cronはサイトにアクセスがあったときに起動する疑似cronであり、システムcronとはまったく別物だという点です。
- wp-cronはサイト訪問者のリクエストをトリガーにするため、深夜にアクセスが少ないサイトでは予定時刻に動かない
- これを安定させるには、
wp-config.phpでDISABLE_WP_CRONをtrueにし、システムcronからwp cron event run --due-nowを定期実行する構成にする - この構成にすると、TZのズレは「システムcron側」を直せばWordPress側も自動的に追随します
弊社が保守しているWordPressサイトはこの構成に統一しており、サイトへのアクセスがない時間帯でも予定どおりにメール送信やバックアップが走るようにしています。
こういう企業に向いている/向いていない
タイムゾーン起因のcronトラブルは、夜間バッチ・定期メール・バックアップなど時刻が業務に直結する処理を運用している中小企業ほど影響が大きくなります。インフラ専任の担当者がいない企業では、こうした「動いているはずなのに動いていない」種類のトラブルが長期間放置されがちです。
一方、すべての処理がオンデマンドで完結しており、定時バッチをそもそも持たないシンプルなサイトであれば、優先度は下がります。
再発防止チェックリスト
timedatectlの出力がAsia/Tokyoになっている- cronデーモンを再起動済み
- crontabに意図しない
CRON_TZが入っていない - ジョブ内のスクリプトをcron相当の最小環境で単独実行して成功している
- WordPressサイトの場合、wp-cronをシステムcronに寄せている
- サーバー移管・OS更新の直後は、TZ設定を再点検する運用にしている
まとめ
cronが指定時間に動かない問題は、見える症状は同じでも、原因は「システムTZ」「cronデーモン」「ジョブ単位TZ」「環境変数」のどこにあるかで対応が変わります。3階層を順に確認する手順を運用に組み込むと、再発を確実に防げます。
本記事は、代表コバが中小企業のサーバー保守の現場で対応してきた知見をもとに、AIを活用して構成・執筆し、弊社にて最終確認を行っています。サーバー運用やバッチ処理の安定化、WordPressサイトの定期処理の見直しなど、具体的な状況をふまえた相談を承っています。費用感だけ知りたい方も、お気軽にご相談ください。