Cloudflare Worker を安全・可逆に自己更新させる、汎用ガーディアン Worker
任意の Cloudflare Worker の前段に置く小さな番人。更新の指示出し・デプロイ後のヘルス検証・失敗時の自動 revert・復旧 UI を担い、ユーザーに Cloudflare を直接操作させない。
Cloudflare Workers では、実行中の Worker が自分自身を安全にロールバックできません。新バージョンがバグると、ロールバックを実行する主体(その Worker 自身)ごと壊れるからです。
WorkerOps は「常に生きている小さな番人」として app Worker の前段に立ち、更新・ヘルス検証・自動 revert・復旧をすべて引き受けます。ユーザーは Cloudflare ダッシュボードを直接触る必要がありません。
- 転送 / Reverse-proxy: 自分専用パス(
OPS_PATH)以外を app Worker へ Service Binding で転送。app 異常時はメンテ画面+復旧 UI を表示。 - 更新 / Update: リリース元から新しい
worker.jsを取得し、Cloudflare API でデプロイ。 - 検証 → 自動 revert: デプロイ後にヘルス検証し、不健全なら直前の安定版(last-good)へ自動で戻す。
- 復旧 UI / Recovery UI: 更新・revert・再導入をボタンで実行。Windows のリカバリ画面のように必要最低限の自己完結 1 画面(外部 CSS/JS 非依存・app 停止中も操作可)。
- 耐久ステート: 更新の各段階を自前 KV に journaling。途中で落ちても Watchdog が後始末。
| 原則 | 内容 |
|---|---|
| Small & stable | WorkerOps 自身はめったに更新しない。コードを最小に保つ。 |
| Project-agnostic | app のデータモデルに依存しない。設定(env)と「Contract」だけで動く。 |
| DB-less | 状態は汎用 KV(WORKEROPS_STATE)。マイグレーションは app に委譲。 |
| Revert-first | 更新直後の不調は「直前の安定版へ戻す」を最優先(CF Versions API、再アップロード不要)。 |
| Reconciliation | KV の記録を信じすぎず、CF の実アクティブ version と app の稼働 version で突合。 |
対象 app は、最大 2 つのエンドポイントを満たすだけで WorkerOps 対応になります。
| 区分 | エンドポイント | 役割 |
|---|---|---|
| 必須 | GET {HEALTH_PATH} |
200 {ok:true, version} を返す。生死+稼働 version の判定に使用。 |
| 任意 | POST {MIGRATE_PATH} |
保留中の one-shot / migration を適用(DB を持つ app 側が実装。追加専用・後方互換)。 |
それ以外の挙動・データモデル・認証は app の自由です。
| キー | 種別 | 用途 |
|---|---|---|
APP_SERVICE |
Service Binding | app への転送・ヘルス検証・migrate 先 |
CF_API_TOKEN |
Secret | CF API で app を更新・revert(Workers Scripts:Edit) |
CF_ACCOUNT_ID / APP_WORKER_NAME |
env | 更新/revert 対象の特定 |
RELEASE_SOURCE |
env | worker.js の取得元(例: GitHub owner/repo) |
OPS_PATH |
env | 予約パス接頭辞(既定 /__workerops__) |
HEALTH_PATH / MIGRATE_PATH |
env | app のヘルス/マイグレーション実行パス |
WORKER_OPS_TOKEN |
Secret | Ops ページ/エンドポイント認証(app 非依存で常に有効) |
WORKEROPS_STATE |
KV | version 状態・更新ログ |
app に紐づく D1/KV/R2/Assets バインドは app Worker 側に付けます。WorkerOps は持ちません。
2 つの操作は 別の障害用。順序を誤らないこと。
- Versions API で last-good へ revert — 更新が原因の不調はこれが第一手(瞬時・再アップロード不要)。
- Release から再導入(reinstall) — Worker の消失/破損/強制再導入の修復用。
- 手動復旧 — CF ダッシュボード / インストーラ(最終手段)。
「再導入」を第一手にしてはいけない。更新が原因の不調では、同じ(壊れた)リリースを入れ直しても直らない。
Cloudflare は更新失敗・接続不可・D1 更新失敗などが 一過性 で起きることがある。WorkerOps はこれをリトライ等で吸収し、利用者に見えなくすることで本体を安定化する。
- 一過性 vs 恒久を分類: 429 / 5xx / 接続 / timeout はリトライ、4xx(認証・検証)は即中止。
Retry-Afterがあれば従う。 - 操作別リトライ+総待ち時間で上限: 通常操作は 3 回(指数バックオフ+ジッタ)、revert は 5 回+Watchdog 継続。ヘルス検証は 30–60s 窓のポーリング。
- 全操作を冪等に: デプロイは version-id 捕捉+reconciliation、migration は run-once+additive-only で再試行安全。
- 伝播遅延対策(version-aware): デプロイ直後は Service Binding が一時的に旧版を返し得る。新版が実際に応答する(health.version が変わる)のを待ってから health/migrate を判定し、壊れた新版を旧版の応答で誤 confirm しない(last-good 汚染防止)。migrate も新版確認後に実行。
- 長時間処理を抱えない:
POST /updateはデプロイ+journaling 後すぐ応答し、検証/revert はwaitUntil+Watchdog で後追い。Ops ページは/statusをポーリング。 - 単一フライト: KV ロックで同時更新を 1 本化(実行中は 409、古いロックは自動解除)。
- 既定値は env 可変:
RETRY_MAX=3/RETRY_BASE_MS=1000/REVERT_RETRY_MAX=5/HEALTH_WINDOW_MS=45000ほか。
「リクエスト内で諦める=失敗確定」ではない。冪等+耐久ステート+Watchdog により、一過性失敗は後追いで完遂・復旧する。
AI やスクリプトから操作できる REST API。前段の app(例: KuroCMS は /api/v1 を使う)と衝突しないよう OPS_PATH 配下に置く(既定 /__workerops__)。操作(update / revert / reinstall)は WORKER_OPS_TOKEN が必須、status / health は公開。
| Method | Path | 認証 | 用途 |
|---|---|---|---|
| GET | {OPS_PATH}/api/v1/health |
不要 | WorkerOps の死活 { ok, service } |
| GET | {OPS_PATH}/api/v1/status |
不要 | 全管理情報(app / tunables / state / cf / health) |
| POST | {OPS_PATH}/api/v1/update |
Bearer WORKER_OPS_TOKEN |
最新リリースへ更新 |
| POST | {OPS_PATH}/api/v1/reinstall |
Bearer WORKER_OPS_TOKEN |
再導入(修復) |
| POST | {OPS_PATH}/api/v1/revert |
Bearer WORKER_OPS_TOKEN |
直前の安定版へ revert |
# 最新へ更新(AI / CLI)
curl -X POST -H "Authorization: Bearer $WORKER_OPS_TOKEN" \
https://<host>/__workerops__/api/v1/update
# 状態確認(公開・認証不要)
curl https://<host>/__workerops__/api/v1/status操作は非同期:
update/reinstallはdeployed_unverifiedを即返し、検証→confirm/自動revert は背後で進む。完了は/api/v1/statusのstate.status(confirmed/reverted/failed_predeploy/manual_required)で確認する。実行中の二重操作は409 update_in_progress。
実装は src/ に集約:
index.ts… proxy(app へ転送)+ Ops ルーティング + scheduled watchdogorchestrator.ts… deployLatest / 検証 / 自動 revert / runRevert / watchdogcf.ts… Cloudflare Versions/Deployments API クライアントhealth.ts… app のヘルス probe / migrate 呼び出し(Service Binding)state.ts… 更新ステート機械(KV journaling)+ 単一フライトロックretry.ts… 一過性分類+指数バックオフのリトライops.ts… Ops API(status / update / revert / reinstall・/api/v1)+ 復旧コンソールconfig.ts/types.ts/util.ts… 設定・型・ユーティリティ
更新は version-aware:デプロイ直後は Service Binding が一時的に旧版を返し得るため、新版が実際に応答してから health / migrate を判定し、誤 confirm(last-good 汚染)を防ぐ。
- 実行時コードの動的ロード不可: Workers は
eval/ リモートimport()を許さない。コードの機能別更新は「別 Worker(app 分離)」でのみ可能。 - スキーマ rollback は対象外: マイグレーションは追加専用・後方互換であること。
- WorkerOps 自身の番人はいない: ごく小さく・滅多に更新しない設計とし、万一壊れたら CF ダッシュボード/インストーラから手動復旧。
- 1 ホップのオーバーヘッド: in-path プロキシのため全リクエストが WorkerOps を経由(同コロ・低コスト)。
✅ コア実装済み — proxy / 更新ステート機械 / CF Versions・Deployments API / リトライ+自動 revert / version-aware 検証 / Watchdog(cron) / 単一フライトロック / 復旧コンソール / REST API。型チェック通過、デプロイ成果物は gzip 約 8 KiB。
最初の利用者は KuroCMS。
WorkerOps は前段(in-path プロキシ)として、app の公開ルートを WorkerOps に向ける。
wrangler.tomlを設定:state KV(WORKEROPS_STATE)の id、APP_SERVICE=前段化する app Worker 名、CF_ACCOUNT_ID、RELEASE_SOURCE、HEALTH_PATH、(任意)MIGRATE_PATH、公開ルート。- secret を設定:
(ローカル
wrangler secret put CF_API_TOKEN # Cloudflare API token (Workers Scripts:Edit + KV:Edit) wrangler secret put WORKER_OPS_TOKEN # Ops 操作の認証
wrangler devでは.dev.varsに同じ値を置く。.dev.vars.example参照) - デプロイ:
wrangler deploy - app 側は WorkerOps Contract を実装:
GET {HEALTH_PATH}→{ ok, version }(必須)、POST {MIGRATE_PATH}(任意・追加専用マイグレーション)。
github.com/Kuro-Boo/WorkerOps
Kuro License(MIT + 帰属表示)。
WorkerOps を 公開/ユーザー向けインターフェース で利用する場合、適切な帰属表示エリア(フッター・About 画面・ドキュメント等)に WorkerOps: Kuro.Boo(https://kuro.boo/ へのリンク付き)を表示してください。WorkerOps 自身の復旧コンソールにはこの帰属表示が含まれています。
Copyright (c) 2026 Kuro-Boo