コンテンツにスキップ

VPS cronジョブの5週間停止(VENVパス誤設定)

📁 docs/ops/postmortem/2026-08-17_vps-cron-venv-path.md

概要

発生日時: 2026-07-12 頃(不明、ログの最終正常実行は2026-07-11) 検知日時: 2026-08-10(#7008、メルカリ監視cron追加の準備調査中に偶然発見) 解消日時: 2026-08-16 ダウンタイム: 約5週間(buzz-collector・task_monitor×2・daily_summary・article-planner)

影響範囲

  • システム: VPS(Oracle Cloud、mylab-vps)上のPython系cronジョブ全般
  • 影響内容: buzz-collector(バズツイート収集)・task_monitor(タスク監視通知)・daily_summary(日次サマリー配信)・article-planner(週次記事企画)が完全停止。task_sync(15分ごと)は失敗ログのみ4.9GB以上蓄積
  • 影響期間: 2026-07-12 〜 2026-08-16

タイムライン

日時 出来事
2026-07-11以前 正常稼働
2026-07-12 頃 $VENV パスが指す実体(/home/ubuntu/.venv/mylab/bin/python)が失われ、全Pythonジョブが not found エラーで失敗開始
2026-08-10 #7008 でメルカリ監視cron追加の準備調査中に発見。リポジトリの crontab.txt は修正されたがVPS実機への反映は未実施のまま保留
2026-08-16 18:20頃 本issue(#7028系のVPS常駐調査)でVPS実機にSSH接続し、6本のログで5週間の全滅を再確認
2026-08-16 18:30頃 git log 調査で、VPSの ~/MyLab チェックアウトがmaster HEADより大きく遅れ、task_syncPR #6956で削除済み)のファイル・stashが残存していることも判明
2026-08-16 18:49 PR #7031 マージ。crontab.txt$VENV を実在するvenvパスに修正
2026-08-16 18:50 VPS上で crontab -l をバックアップ後、修正済み crontab.txt を反映。task_monitor.py の手動実行で復旧を確認(exit 0)
2026-08-16 18:52 4.6GBに肥大化していた task-sync.log を削除

原因

直接原因

scripts/vps/cron/crontab.txtVENV 変数が /home/ubuntu/.venv/mylab/bin/python という存在しないパスを指していた。実在するvenvは /home/ubuntu/MyLab/venv(Discord Botのsystemdサービスが使用中で、こちらは影響を受けていなかった)。

根本原因

  1. crontab.txt 自体のコメントに「変数(実際のパスに書き換えること)」というテンプレートのプレースホルダーが残っており、その指示が実行されないままVPSにインストールされた
  2. VPS実機へのcrontab反映が手動オペレーション(crontab scripts/vps/cron/crontab.txt の実行)に依存しており、リポジトリ側のファイル修正だけでは実運用に反映されない設計だった
  3. Discord通知等の失敗検知の仕組みがcronジョブ自体に組み込まれていなかったため、5週間気づかれなかった

修正内容

# crontab.txt側の修正(PR #7031)
- VENV=/home/ubuntu/.venv/mylab/bin/python
+ VENV=/home/ubuntu/MyLab/venv/bin/python

# buzz-collectorはconfig/config.yamlを相対パスで開くため cd を追加
- 0 8 * * * $VENV $MYLAB/projects/buzz-collector/main.py --all-genres >> $LOG/buzz-collector.log 2>&1
+ 0 8 * * * cd $MYLAB/projects/buzz-collector && $VENV main.py --all-genres >> $LOG/buzz-collector.log 2>&1

# VPS実機への反映
ssh mylab-vps 'crontab -l > ~/crontab.bak.$(date +%Y%m%d_%H%M%S)'
scp crontab.txt(origin/master最新) mylab-vps:/tmp/crontab_new.txt
ssh mylab-vps 'crontab /tmp/crontab_new.txt'

# 肥大化ログの削除
ssh mylab-vps 'rm -f ~/MyLab/logs/cron/task-sync.log'  # 4.6GB

再発防止策

対策 担当 期限 状態
cronジョブ失敗時にGoogle Chat等へ通知する仕組みを追加 未定 未定 ⬜ 未着手
VPSの ~/MyLab を定期的に git pull し、リポジトリとの乖離を防ぐ仕組み(現状は手動 or 一部cronのみ) 未定 未定 ⬜ 未着手
crontab.txt 変更後にVPS実機への反映を忘れないよう、PRテンプレートかチェックリストに明記 未定 未定 ⬜ 未着手

学んだこと

  • テンプレートのプレースホルダー(「実際のパスに書き換えること」)は、書き換えを強制する仕組み(CIチェック等)がない限り本番投入時に見落とされる
  • リポジトリ内の設定ファイル修正と、それを参照する本番環境(VPS crontab)への反映は別工程であり、前者の完了を後者の完了と混同しないこと(#7008では完了条件のチェックボックスとして両方が並んでいたが、リポジトリ側の[x]だけが先に付き、VPS反映は長期間見落とされていた)
  • 定期実行ジョブは「失敗しても気づかれない」設計だと、失敗が長期化しやすい。実行結果の可視化(成功/失敗の通知)が事後対応より重要

関連リンク