Rollback Runbook

SSoT 参照: 通知ルーティング (severity / channel / mention / format) は notification-strategy.md、 インシデント全体トリアージは incident-response.md、 SLO / Error Budget は slo-error-budget.md。 本 runbook は 「悪いデプロイを 1 コマンドで戻す」手順のみ扱う。

1. 概要 — いつ rollback が必要か

Rollback は fast revert の手段であり、根本原因が確定する前でもユーザー影響を止めるために走らせる。「直すより戻すほうが速い」ときに迷わず引く。

  • 本番デプロイ直後(〜30 分以内)に明らかな regression が出たとき
  • SLO の error rate / latency が baseline × 3 を超えて 5 分継続したとき
  • 外部 synthetic healthcheck が連続 3 回失敗したとき (synthetic-healthcheck.md)
  • 新 deployment 起因の Sentry 高頻度 unhandled exception を検知したとき

Rollback は恥ずかしいことではない。原因が見えていなくても、ユーザーに当てている時間を最小化することが最優先。

2. 判断基準

シグナル閾値判断
Sentry error rate baseline × 3 を 5 分継続 P0 即時 rollback
p99 latency 1s 超を 10 分継続 P0 即時 rollback
Synthetic /healthz/ready 連続 3 回失敗 (cron-checks) P0 即時 rollback
5xx rate (Workers Logs) 1% 超を 10 分継続 P1 5 分以内に rollback 判断
主要機能の 4xx 急増 (auth / payment) baseline × 5 を 10 分継続 P1 5 分以内に rollback 判断
個別ユーザーからの bug 報告 再現性なし / 1 件のみ P2 rollback せず追跡継続

3. 手順 (Workers — parky-api-{env})

3.1 ワンコマンド rollback (推奨)

# prod は --confirm 必須。reason は Discord 通知に出るので必ず入れる。
./scripts/deploy/rollback.sh api prod --confirm --reason="Sentry error rate spike (baseline x4)"

# dev / stg は --confirm 不要
./scripts/deploy/rollback.sh api dev

このスクリプトが内部で行うこと:

  1. 現在の deployment 一覧を表示 (rollback 先を視認)
  2. wrangler rollback --name parky-api-{env} を実行
  3. scripts/deploy/health-probe.sh https://api.parky.co.jp/healthz/ready を 3 回叩いて 200 OK を確認
  4. Discord #p0-alertsSTART → DONE / FAILED を通知

3.2 特定 deployment ID への rollback

# 履歴確認
wrangler deployments list --name parky-api-prod | head -n 20

# ID 指定して rollback
./scripts/deploy/rollback.sh api prod --confirm \
  --version 12345678-aaaa-bbbb-cccc-dddddddddddd \
  --reason="revert to known-good before payment refactor"

3.3 dry-run (計画のみ表示)

./scripts/deploy/rollback.sh api prod --dry-run --reason="checking command shape"

3.4 PowerShell から呼ぶ場合 (Windows ローカル)

.\scripts\deploy\rollback.ps1 api prod --confirm --reason "Sentry spike"

4. 手順 (Pages — Portal / Home / Public)

重要: wrangler pages deployment は version によって rollback サブコマンドを持たない。 持っていれば ./scripts/deploy/rollback.sh admin prod --confirm --version <id> が動くが、 持っていない場合スクリプトは Dashboard 手順を案内するだけで終了する (誤動作させないため)。

4.1 CLI が rollback 対応している場合

# 履歴確認 (Production deployment 限定)
wrangler pages deployment list --project-name parky-portal-admin

# version ID を指定して rollback
./scripts/deploy/rollback.sh admin prod --confirm \
  --version 12345678-aaaa-bbbb-cccc-dddddddddddd \
  --reason="bad portal release"

4.2 Dashboard 手順 (CLI 非対応 Pages の fallback)

  1. https://dash.cloudflare.com/Pages → 対象プロジェクト
  2. Deployments タブで戻したい成功 deployment を選択
  3. 「Rollback to this deployment」 ボタンをクリック
  4. 完了後、健全性確認:
    bash scripts/deploy/health-probe.sh https://admin.parky.co.jp/healthz/ready
  5. Discord #p0-alerts に手動で完了通知 (rollback.sh 経由なら自動)

4.3 git revert 経由 (CD 待ちでも良い場合)

  1. git revert <bad-sha> → push
  2. 対応する .github/workflows/deploy-*.yml が走って Pages を上書き
  3. build に 2-5 分かかるため、即時止血が必要なら 4.1 / 4.2 を優先

5. 手順 (Supabase migration)

原則: migration は rollback しない。対応する 新規 revert migration を作って前進方向に戻す。 これは Parky 全体ルール (CLAUDE.md / memory feedback_parky_datamodel_change_flow) として確立済み。

5.1 やってはいけないこと

  • infra/supabase/baseline/ 配下の手編集 (生成物のため drift する)
  • supabase db reset を本番で実行
  • 過去の migration ファイルを削除 / 改変

5.2 正しい手順

  1. 問題のある変更を特定 (例: ALTER TABLE による列 default の破壊的変更)
  2. 同じテーブル単位ファイルに 追記で revert SQL を書く (べき等)
  3. dev DB に apply_migration で適用 → 動作確認
  4. bash scripts/db/refresh-baseline.sh で baseline 更新
  5. アプリ側コード変更と同じ PRで commit (data 層 / OAS / FE まで一括)
  6. CI baseline-drift.yml / api-rls-tests が green になるまで merge しない

5.3 アプリ rollback と DB の関係

状況対応
アプリ rollback だけで解消 (DB schema 変更なし) Workers / Pages を rollback して終了
新 deployment が新 column / 関数を要求している DB 側は 前方互換のまま残す (drop しない)。アプリだけ rollback すれば旧コードは新 column を無視する
新 deployment が既存 column の意味を破壊した アプリ rollback + 新 revert migration を急遽追加 (5.2 の手順)

6. 検証

6.1 health-probe.sh での確認

bash scripts/deploy/health-probe.sh https://api.parky.co.jp/healthz/ready
echo "exit code: $?"   # 0 = 3/3 OK / 1 = 1 件以上失敗

6.2 Sentry / Workers Logs での確認

  • Sentry: sentry.io → Issues → 直近 30 分の error rate が baseline に戻ったか
  • Workers Logs: npx wrangler tail --config wrangler.<worker>.toml --env prod で 5xx / unhandled exception の頻度を目視 (4 split worker の該当を選択 — public / admin / marketing / store-sync)
  • Synthetic healthcheck: synthetic-healthcheck.md の cron job が green に戻るのを確認

6.3 deployment id の記録

# split worker 後 (2026-04-30 ~) は --config 必須
cd parky/api
npx wrangler deployments list --config wrangler.public.toml --env prod | head -n 5
# 現在 active な deployment id を postmortem の timeline に貼る
# admin / marketing / store-sync も該当 worker のみ調べる

7. 事後対応

7.1 Discord 完了通知

rollback.sh は自動で #p0-alerts (P0 / P1) に START / DONE / FAILED を投げる。手動 Pages rollback の場合は以下を貼る:

@here
:rotating_light: **[P1] Rollback DONE**
target=admin env=prod
reason=portal SSR error spike
deployment=<new id> (was <bad id>)
verified=health-probe 3/3 OK

7.2 ポストモーテム

  • テンプレート: postmortem-template.md
  • 保管先: docs/ops/postmortems/YYYY-MM-DD-<title>.md
  • 必須記載: 検知 → 判断 → rollback 実行 → 検証 の各ステップの JST 時刻
  • action item は SMART (Specific / Measurable / Assignee / Realistic / Time-boxed)

7.3 再発防止 checklist

  • 失敗を検知したアラート / synthetic check の閾値は妥当だったか (早く / 遅く 検知)
  • CI で fail させられた regression だったか → test を追加
  • Canary / staged rollout を入れる余地はあるか (Phase 2+)
  • rollback.sh の出力 / Discord 通知に改善点はあるか

8. 付録

8.1 必要な環境変数

変数用途取得元
CLOUDFLARE_API_TOKEN wrangler が CF API を叩く op-cache 経由 (scripts/op-cache/op-cache.sh get-secret cloudflare/api-token)
DISCORD_WEBHOOK_ALERTS rollback START/DONE/FAILED 通知 op-cache 経由 (scripts/op-cache/op-cache.sh get-secret discord/webhook-alerts)

8.2 関連 docs

8.3 ファイル位置

ファイル役割
scripts/deploy/rollback.sh本体スクリプト (bash)
scripts/deploy/rollback.ps1Windows / PowerShell ラッパ
scripts/deploy/health-probe.sh3 回 curl で /healthz/ready を確認
docs/ops/rollback-runbook.html本 runbook (このページ)