Back

Cron ジョブで繰り返しタスクを自動化する

Cron ジョブで繰り返しタスクを自動化する

古いログをクリアしたり、データベースをバックアップしたり、キャッシュをウォームアップしたりするスクリプトを書いたとします。手動で実行すると完璧に動作します。しかし今度は、毎晩午前2時に手動介入なしで実行する必要があります。ここで cron が不可欠になります。

Cron は、現代の Linux システムでスクリプトをスケジューリングするための標準ツールであり続けています。その仕組みと代替手段を使うべきタイミングを理解することで、サイレント障害やデバッグの手間から解放されます。

重要なポイント

  • Cron は Unix 系システムに組み込まれた時間ベースのジョブスケジューラーで、5つのフィールド構文を使用して指定された間隔でコマンドを実行します
  • Cron は最小限の環境で実行され、カスタム PATH 設定が含まれないため、cron ジョブでは常に絶対パスを使用してください
  • サイレント障害を避けるために、ログ記録を追加し、flock でジョブの重複を防ぎ、タイムゾーンの問題を考慮してください
  • コンテナ化またはクラウドネイティブ環境では、従来の cron の代わりに Kubernetes CronJobs、AWS EventBridge、またはアプリケーションレベルのスケジューラーを検討してください

Cron とは何か、どのように動作するのか?

Cron は Unix 系システムに組み込まれた時間ベースのジョブスケジューラーです。バックグラウンドデーモンが設定ファイル(crontab)を読み取り、指定された間隔でコマンドを実行します。

Crontab には2つのタイプがあります:

  • ユーザー crontab: 各ユーザーが crontab -e を介して独自のスケジュールを管理します
  • システム crontab: /etc/crontab/etc/cron.d/ に配置され、ユーザー名フィールドを含み、システム全体のタスクを処理します

Cron デーモンは毎分これらのファイルをチェックし、スケジュールが現在時刻と一致するジョブを実行します。

Cron 構文の理解

すべての cron ジョブは、5つのフィールドからなる時刻指定に従います:

┌───────────── 分 (0-59)
│ ┌───────────── 時 (0-23)
│ │ ┌───────────── 日 (1-31)
│ │ │ ┌───────────── 月 (1-12)
│ │ │ │ ┌───────────── 曜日 (0-6, 日曜日=0)
│ │ │ │ │
* * * * * /path/to/command

実用的な例:

# 毎晩午前2時にバックアップスクリプトを実行
0 2 * * * /home/deploy/scripts/backup.sh

# 毎週日曜日の午前3時に一時ファイルをクリーンアップ
0 3 * * 0 /usr/bin/find /tmp -type f -mtime +7 -delete

# 営業時間中、平日のみ15分ごとに実行
*/15 9-17 * * 1-5 /home/deploy/scripts/health-check.sh

デプロイ前に crontab.guru を使用して式を検証してください。

Cron ジョブでタスクを自動化するための重要なベストプラクティス

絶対パスを使用する

Cron は最小限の環境で実行されます。あなたの PATH には /usr/local/bin やカスタムディレクトリが含まれていない可能性があります。常にフルパスを指定してください:

# 誤り - サイレントに失敗する可能性があります
0 2 * * * backup.sh

# 正しい
0 2 * * * /home/deploy/scripts/backup.sh

Cron の限定的な環境を理解する

Cron は .bashrc.profile を読み込みません。nvm、rbenv、pyenv などのバージョンマネージャーは利用できません。明示的にそれらを source するか、特定のバイナリへの絶対パスを使用してください。

ログ記録とアラートを追加する

出力のリダイレクトがないと、cron の失敗は気づかれません:

0 2 * * * /home/deploy/scripts/backup.sh >> /var/log/backup.log 2>&1

重要なジョブについては、Healthchecks.ioCronitor などの監視サービスと統合してください。

ジョブの重複を防ぐ

長時間実行されるタスクは、次のスケジュール実行が開始されるときにまだ実行中かもしれません。flock を使用して重複を防ぎます:

0 * * * * /usr/bin/flock -n /tmp/report.lock /home/deploy/scripts/generate-report.sh

最小権限の原則を適用する

すべてを root として実行しないでください。特定のタスク用に専用のサービスアカウントを作成し、システム全体の設定ではなくユーザー crontab を使用してください。

タイムゾーンと夏時間の問題に注意する

Cron はシステム時刻を使用します。夏時間の切り替えにより、ジョブが2回実行されたり、スキップされたりする可能性があります。重要なスケジューリングには、UTC の使用を検討してください。

自動化のための Cron vs Systemd タイマー

Systemd ベースのディストリビューションでは、タイマーは検討する価値のある利点を提供します:

機能CronSystemd タイマー
ログ記録手動設定journald に組み込み
実行漏れスキップキャッチアップ可能
依存関係なしsystemd との完全統合
リソース制限手動cgroups に組み込み

VM 上のシンプルなホストレベルの自動化には、cron が適しています。依存関係管理やより良い可観測性が必要な場合は、systemd タイマーは追加の設定に値します。

コンテナ化およびクラウドネイティブ環境での Cron ジョブ

従来の cron はコンテナにうまく適合しません。アプリケーションと並行して cron デーモンを実行することは、コンテナごとに単一プロセスという原則に違反します。

より良い代替手段:

  • Kubernetes CronJobs: 組み込みのリトライロジックを持つコンテナ化されたワークロードのネイティブスケジューリング
  • AWS EventBridge または GCP Cloud Scheduler: スケジュールに基づいて Lambda 関数や Cloud Run サービスをトリガー
  • アプリケーションレベルのスケジューラー: Node.js アプリ用の node-cron などのツール

Web 開発者にとって、小規模な VM 上の cron は、メインアプリケーションが他の場所で実行されている場合でも、メンテナンススクリプトのトリガー、定期レポートの生成、キャッシュのウォームアップに使用できます。

まとめ

Cron は、シンプルなホストレベルの自動化に優れています:バックアップスクリプト、ログローテーション、証明書更新チェック、定期的なクリーンアップなど。軽量で、どこでも利用でき、追加のインフラストラクチャを必要としません。

分散スケジューリング、コンテナオーケストレーション、または高度な障害処理が必要な場合は、代替手段を選択してください。概念は同じです—現代のスケジューラーが cron の構文を採用したのには十分な理由があります。

単一の十分にテストされたジョブから始め、適切なログ記録を追加し、そこから構築していってください。

よくある質問

Cron は .bashrc や .profile などのシェル設定ファイルを読み込まない最小限の環境で実行されます。つまり、カスタム PATH 設定やバージョンマネージャーが利用できません。すべてのコマンドとスクリプトに絶対パスを使用するか、cron コマンドの開始時に環境ファイルを明示的に source することで修正してください。

まず、systemctl status cron で cron が実行されているか確認してください。次に、crontab -l で crontab 構文を検証します。>> /path/to/log 2>&1 を使用して出力をファイルにリダイレクトしてログ記録を追加します。/var/log/syslog または /var/log/cron のシステムログでエラーメッセージを確認してください。また、スクリプトに実行権限があることを確認してください。

ユーザー crontab は crontab -e を介してユーザーごとに管理され、そのユーザーとしてコマンドを実行します。/etc/crontab と /etc/cron.d/ のシステム crontab には、コマンドを実行するユーザーを指定する追加のユーザー名フィールドが含まれています。システム crontab は通常、システム全体のメンテナンスタスクに使用され、編集には root アクセスが必要です。

さまざまな Unix 系システムで実行する必要があるシンプルで移植性の高いスクリプトには cron を使用してください。journald を介した組み込みログ記録、実行漏れのキャッチアップ機能、他のサービスとの依存関係管理、または cgroups を介したリソース制限が必要な場合は systemd タイマーを選択してください。Systemd タイマーはより多くの設定が必要ですが、より良い可観測性を提供します。

Gain control over your UX

See how users are using your site as if you were sitting next to them, learn and iterate faster with OpenReplay. — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay