← 記事一覧
サーバーメンテナンス中の共有ホスティングサイトを守るCloudflareエッジネットワーク
まずorigin、必要時だけスナップショット1つのドメイン、自動障害処理、手動復旧スイッチなし。

共有ホスティングサイトをCloudflare Workersでサーバー保守に備えた方法

公開 · 更新

要点

静的要素が中心のPHPサイトなら、ライブアカウントを移さず、計画停止中も多くの機能を残せます。KeyboardTester.clickの前段に置いたWorkerは、正常なオリジン応答を変更せず通し、ネットワーク障害や対象のサーバーエラー時だけ静的スナップショットを返します。オリジンが回復すれば次の正常リクエストで自動復帰します。ただし万能なゼロダウンタイムではなく、フォーム、メール、サーバー側AI、保存処理はオリジン依存のままです。

通知には6時間の作業枠だけが示され、実停止時間は不明でした。障害メールを待つと手動切替の空白が生じ、単一のメンテナンスページでは本来のページやブラウザツールを提供できません。

ここでは実際に導入した構成を、HostArmadaとの確認、Workerの判定、スナップショット、同一ゾーンの再帰、無料枠、SEO・広告・解析、制約までまとめます。

時点の注意:2026年7月18日現在、予定保守はまだ実施されていません。結果は強制origin障害、非公開staging、全件監査、正常な本番通過テストによるもので、実際の保守時間の結果ではありません。

HostArmadaのチケットで確認できたこと

作業枠は2026年7月22日10:00~16:00 CDTでした。6時間連続停止なのか、仮移行できるか、影響サービス、全URLに外部から503を返せるか、復旧・補償を質問しました。

エスカレーション後、6時間は予約枠であり停止確定時間ではない、実停止は短い見込みだが、物理作業・更新・検証のため正確には出せないとの回答でした。アカウントを往復移行するとDNS、同期、メール、DB整合性のリスクが増えます。

影響外サーバーに一時vhostとメンテナンスページを置き、開始時と終了時にAレコードを手動変更する案も提示されました。外部DNSは解決を続けますが、Web、DB、メール、パネルは停止します。バックアップと復旧手順はあり、クレジットは実影響後に審査する方針でした。案は妥当な告知手段ですが、手動で機能継続ではありません。

That offer was fair for a maintenance notice. It was still manual and did not provide functional-site continuity, so we used it as the baseline to improve rather than portraying it as a provider failure.

検証可能な時系列:保守メールからテスト済み継続層まで

提供者の告知、こちらの質問、実際に構築・試験した内容、まだ未来の実イベントを明確に分けます。

  1. 2026年7月 — 保守メール受信

    Start Dock共有サーバーの通知は7月22日10:00–16:00 CDTを確保。CPU/RAM/SSD、Webサーバーのsecurity/software、kernel、tmp/cache/log清掃、全般最適化を列挙し、開始後は不可逆と説明しました。

  2. 7月16日 — 質問をescalate

    実停止時間、仮移行、外部503、Web/DB/mail、backup、rollback、creditを質問。

  3. 7月17日 — HostArmada回答

    6時間は枠、停止は短い見込みだが不明。同期リスクで移行を拒否し、vhostと手動A recordを提案。

  4. 枠と仮vhostを説明するサニタイズ済み回答
    個人・基盤情報を除いた英語原文のsupport証拠です。上の日本語時系列が内容を要約します。
  5. 7月17日に設計選択、18日にフォローアップ送信

    常設origin-first Worker、snapshot、非公開staging、衝突検査、503、rollbackを採用。

  6. Cloudflare継続層への判断を示すサニタイズ済みfollow-up
    サニタイズ済み英語原文のfollow-upです。隣の日本語HTMLが判断を説明します。
  7. 7月17–18日 — 制御試験

    1,514 page、1,234 asset、2,748 pathを監査し、障害/通過、再帰修正、apex/www fail-openを検証。

  8. 7月18日 — 準備済み、実イベント前

    層はliveかつテスト済みですが22日の保守は未実施。実時間、traffic、収益は事後証拠が必要です。

構成:まずオリジン、障害時だけスナップショット

Workerはapexとwwwの経路に常駐し、制限時間付きで実オリジンを確認します。正常応答はそのまま返すため、PHP、セッション、ヘッダー、広告、解析は通常どおりです。

ネットワーク障害、タイムアウト、500/502/503/504または520–527では同じパスの静的資産を返します。GET/HEADは継続し、以後も毎回オリジンを試すため自動復帰します。

第二のPHP環境ではないため、書き込み可能DBの二重化、セッション衝突、事後のデータ突合を避けられます。

リクエストの流れ

Cloudflare経路で受信apexとwwwが同じWorkerへ。
Workerがオリジン確認公開経路へ戻らない時間制限付き要求。
正常応答を通過PHP、セッション、計測は通常どおり。
障害時はコピーGET/HEADは該当パス、書き込みは503。
自動復帰次の正常オリジン応答が即時復帰。
Cloudflareスナップショットから復旧したホスティングoriginへ自動復帰する流れ
originへ自動復帰以後の各要求がホストを試し、正常応答はすぐ通過します。
復旧スイッチは不要です。以後の各リクエストがoriginを試し、正常応答がサービスを再開します。

一時メンテナンスページと常設Workerの比較

正しい保守通知だけなら前者が簡単です。読み取りページやクライアント側ツールを残したい場合は、準備と検証を伴う後者が適します。

項目一時vhost常設Worker
切替開始・終了時にDNSを手動変更リクエストごとに自動
表示1枚の保守ページ該当ページ・ツール・資産
書き込み不可不可、明示的503
復旧DNSを手動で戻すオリジン正常時に自動
整合性第二DBなしで低リスク第二DBなしで低リスク
運用単純だが定刻作業が必要準備は多いが当日の操作は少ない

利用者とクローラーへの障害時応答

ページ、ブラウザツール、CSS、スクリプト、画像、フォントは小さな縮退表示付きでスナップショットから配信し、canonicalと構造化データは元URLを保ちます。

書き込みは成功を装いません。POSTなど利用不能な操作には503 Service UnavailableRetry-After: 300Cache-Control: no-storeを返します。RFC 9110は503を一時障害・計画保守に定義しています。

This distinction matters: returning a pretty 200 OK “maintenance” page for a failed form can mislead users and crawlers. Returning a controlled 503 for the unavailable action is both more honest and easier for clients to retry.

実際のfallback判定表

origin結果GET / HEADPOST・書き込み
正常、redirect、4xx、対象外statusoriginを無変更で通過originを無変更で通過
network失敗・4.5秒timeout該当snapshot、なければ503503 + Retry-After: 300 + no-store
500/502/503/504・520–527snapshotと診断header503 + Retry-After: 300 + no-store
origin停止中の未知safe path制御503。ページを捏造しない対象外

スナップショットの構築と検証

未公開変更を含むローカルPHPではなく、レンダリング済み本番をクロールしました。1,514ページ1,234個の自社資産を取得し、最終的に2,749ファイル、約547.6 MBとなりました。各ファイルは上限内です。

canonicalとschemaを保持し、古い相対参照はコピー内だけ修正。取得時にトラッカーを外し、本番WorkerだけがGA4、AdSense、トップページClarityを遅延追加します。非公開stagingは追跡なし、noindexです。

TypeScript、単体、ローカル強制障害、認証staging、ブラウザ、origin preview、全件リモート監査を実施し、公開2,748パスすべて成功しました。

公開前に静的フェイルオーバーを検証する非公開staging環境
公開ルート前の非公開staging認証、noindex、強制障害、origin比較、承認の順に確認。
強制障害とページ検証の間、プレビューは非公開・noindex・追跡なしに保ちました。

安全に再現する手順とサニタイズ済みコード

1. 契約を先に定義。対象host、安全なmethod、fallback status、timeout、未知path、route削除を決めます。non-200全てが障害ではありません。

2. レンダリング済み本番をcrawl。canonical sitemapからsame-originのHTML/CSS資産だけを集め、URLを正規化し、traversalを防ぎ、個数・サイズ超過でbuildを止めます。

3. 意味を保持。canonical、hreflang、schema、リンク、client tool資産を残し、service workerとtrackingをコピーから外します。広告・解析はproductionだけで挿入します。

4. ASSETSrun_worker_firstコピー前にoriginを確認します。例はplaceholderのみです。

5. 同一zone再帰を防止。管理下のDNS-only名をresolveOverrideに使い、URL/Hostを維持し、TLS/vhostを確認します。

6. 非公開staging。secret、noindex、robots遮断、広告/解析なし、origin previewを用意します。

7. apex、次にwww。衝突を拒否しredirectを検証。fail-openは可用性用途だけにします。

8. rollbackを分離。所有routeだけ削除し、Worker/snapshotは保持、臨時権限を失効します。

サニタイズ済みWorker/asset設定

{
  "name": "example-host-outage-fallback",
  "main": "src/index.ts",
  "compatibility_date": "2026-07-17",
  "assets": {
    "directory": "./snapshot/dist",
    "binding": "ASSETS",
    "run_worker_first": true,
    "html_handling": "none",
    "not_found_handling": "none"
  },
  "vars": {
    "MODE": "production",
    "ORIGIN_BASE": "https://example.com",
    "ORIGIN_RESOLVE_OVERRIDE": "origin-bypass.example.com",
    "ORIGIN_TIMEOUT_MS": "4500"
  }
}

origin-first判定とstatus

const FALLBACK_STATUSES = new Set([
  500, 502, 503, 504, 520, 521, 522, 523, 524, 525, 526, 527
]);

try {
  const origin = await fetch(originRequest, {
    signal: AbortSignal.timeout(4500),
    redirect: "manual",
    cf: { resolveOverride: "origin-bypass.example.com" }
  });
  if (!FALLBACK_STATUSES.has(origin.status)) return origin;
  return serveSnapshot(request, origin.status);
} catch {
  return serveSnapshot(request);
}

書き込みへの正しい503

if (!new Set(["GET", "HEAD"]).has(request.method)) {
  return new Response("Temporarily unavailable", {
    status: 503,
    headers: {
      "Retry-After": "300",
      "Cache-Control": "no-store",
      "Content-Type": "text/plain; charset=utf-8"
    }
  });
}

build、staging、activate、rollback

# Build from rendered production and validate the package
python scripts/build_snapshot.py
npm run types
npm run check
npx wrangler deploy --env staging --dry-run

# Deploy and test the private preview (use your own secret securely)
npx wrangler deploy --env staging
python scripts/smoke_staging.py --base "https://<private-preview>" --password "<secret>"

# Inspect, activate, or remove only the owned routes
python scripts/manage_routes.py status
python scripts/manage_routes.py activate --confirm ACTIVATE-KBT-FALLBACK
python scripts/manage_routes.py deactivate --confirm REMOVE-KBT-FALLBACK

テスト計画:障害・通過・復旧を証明

トップ、主要tool、CSS/JS、記事、Arabic RTL、長い翻訳、robots、missing path、HEADPOST、www redirect、mobile light/darkを確認します。

snapshotではheader、canonical、H1、JSON-LD、資産、通知。origin previewではloopなし。正常productionではfallback headerなしと無変更応答を確認します。

公開originを故意に壊さず、非公開previewまたは別test originを使い、生成時刻とmanifest hashを記録します。

ロールバック、監視、復旧

即時rollbackは所有Worker routeだけの削除です。DNS変更やWorker削除ではありません。apex/wwwを確認し、古いfallback HTMLがある場合だけpurgeします。

保守中はheader、origin status、log、主要page、503を監視。最初の正常応答で自動復帰します。後で安定性確認、臨時権限失効、測定保存、snapshot更新を行います。

2つの落とし穴:同一ゾーン再帰と無料上限

keyboardtester.click/*のWorkerが同じ公開ホストを単純fetchすると自分に戻る恐れがあります。同一ゾーンの既存DNS-only名へresolveOverrideし、URLとHostはcanonicalのままオリジンへ解決しました。オリジンIPや迂回経路は公開しません。

Freeは現在1日100,000 Workerリクエスト、1バージョン20,000静的ファイル、1ファイル25 MiBです。2,749ファイルは範囲内。ルートはfail-openで、枠超過時はError 1027ではなくHostArmadaへ直接迂回します。可用性用途には適しますが、セキュリティ強制には不適切です。

フォールバック中のSEO・広告・解析

存在するコピーは元URLで200、canonical、schema、内部リンクを保ち、利用不能な書き込みだけ503です。公開ミラードメインや新規送信URLはありません。

stagingはパスワード、robots遮断、noindex、計測なし。本番コピーHTMLだけに遅延GA4/AdSense、トップページだけClarityを追加し、正常オリジン応答は変更しません。計測と広告配信の可能性は残りますが、広告充足や収益は保証できません。

We did not submit fallback URLs to search engines because there are no new public URLs. The continuity layer sits behind the same addresses Google already knows.

production挿入はlive性能に合わせ、GA4は操作後またはload 2秒後、AdSenseは操作後または15秒後、トップClarityは操作後または12秒後です。streaming HTMLRewriterはfallback GET HTMLだけを変更し、HEAD、CSS、JS、画像は変更しません。

制約と別方式を選ぶ場面

フォーム、サーバーAI、メール、DB書き込み、セッション、保存送信はオリジン停止中に使えません。ブラウザ内ツールも必要ファイルが全てコピーされている場合だけ動きます。

コピーは古くなるため、大きな変更後に更新し、障害だけでなく復旧も試験します。書き込み・取引中心の製品はアプリとDBの複製が必要です。

コンテンツ中心でクライアントツールが多い共有サーバーには、データ分岐、手動切替、別公開ドメインなしで明確な縮退運転を作れる適切な方法でした。見える停止を短くしますが依存を全廃はしません。

一次資料と実測根拠

数値は2026年7月17~18日のマニフェスト、デプロイ、実経路検証によるものです。製品仕様と上限はリンク先の一次資料に基づきます。

よくある質問

  • 共有サーバーが本当にゼロダウンタイムになりますか?

    いいえ。読み取りコピーは残りますが、フォーム、書き込み、メール、AI、セッションはオリジンが必要です。

  • 障害時にDNS変更が必要ですか?

    この常設方式では不要です。Workerが毎回確認し自動復帰します。

  • Googleは全URLで保守ページを見ますか?

    いいえ。コピー済みページは200とcanonical/schemaを保ち、利用不能な操作だけ一時503です。

  • なぜアカウント全体を一時移行しないのですか?

    往復移行はDNS、ファイル、メール、DB同期の危険を増やすためです。

  • resolveOverrideはなぜ必要ですか?

    Workerが自分の公開経路を再呼び出さないためです。同一ゾーンの別名で解決し、URLとHostは維持します。

  • 無料上限に達すると?

    fail-openでWorkerを迂回しオリジンへ行きます。オリジン停止時のコピーは失いますが追加の枠エラーを防ぎます。

  • いつコピーを更新しますか?

    大きなコンテンツ・テンプレート・スクリプト・資産変更後と計画保守前です。

重要なのは全てをWorkerに置くことではなく、障害に合う最小の継続層を選び、非公開で試し、限界を示し、復旧を自動化することです。

Windowsアプリ

KeyboardTester.click は Microsoft Store でも利用できます

公式Windowsショートカットをインストールするか、ブラウザで同じ無料ツールを使えます。

Microsoft Store からダウンロード Microsoft Store からダウンロード