既存システムをCloudflare Workersに移行する際、「どこから手をつければいいのか分からない」「移行中のダウンタイムが心配」という悩みを抱える中小企業のWeb担当者は多いものです。実は、段階的な3ステップで低リスクに実現できます。
この記事では、既存システムからCloudflare Workersへの移行を成功させるための実践的な手順、よくある失敗パターン、実装チェックリストをお伝えします。複数サイト移行の事例から学んだ知見に基づき、ダウンタイムなしで段階的に移行する方法を解説します。
移行前に確認すべき評価ポイント

既存システムをCloudflare Workersにマイグレーションする際、まず重要なのは「今あるシステムの全体像を把握すること」です。多くの企業がこの段階を飛ばして技術選定に進み、後になって予期しない制約に気づいて計画が頓挫しています。
現在のシステムを評価する際、押さえるべきポイントは5つです。第一に、API呼び出しの頻度とレイテンシ要件です。Workersは1リクエストあたりのCPU時間に制限があるため(無料プラン50ms、有料プラン30秒)、複雑さによって向き・不向きが分かれます。第二に、データベースの規模と更新頻度です。Workersと組み合わせるD1は小~中規模データに最適ですが、大規模なリレーショナルデータベースを運用している場合は外部データベース連携が必要です。
第三に、認証・認可の複雑さを確認してください。OAuth、SAML、カスタム認証を使っている場合、Workersでの実装難度が大きく異なります。第四は、ファイルアップロード・ストレージの仕様です。WorkersはR2と組み合わせれば大容量ファイル処理を実装できます。第五に、既存のサードパーティAPI連携(決済、CRM、メール配信など)の数と複雑さを把握することです。
| 評価項目 | 低リスク | 要検討 | 要対策 |
|---|---|---|---|
| API応答時間 | <100ms | 100-500ms | >500ms |
| DBサイズ | <100MB | 100MB-1GB | >1GB |
| 認証方式 | JWT/Session | カスタム実装 | レガシー認証 |
| ファイル処理 | テキスト・画像 | 動画変換 | ストリーミング |
| 外部API連携数 | 1-3個 | 4-10個 | 10個以上 |
この表から自社システムのカテゴリを判定することで、移行難度と必要なリソースが見えてきます。低リスク側に寄っていれば段階的な移行計画で成功しやすいシステムです。
ステップ1と2:段階的な機能移行戦略

Cloudflareへのマイグレーションでは、一度にすべてを変更するのは禁物です。
ステップ1:CDN・DNS導入(ローリスク導入)
既存システムはそのまま維持しながら、Cloudflareのキャッシュ層とセキュリティ層だけを挿入するのが最小変更の鉄則です。このステップにより、トラフィック削減(キャッシュヒット率70%以上)、DDoS防御、ボット対策が実現され、既存サーバーに変更を加えないまま恩恵を受けられます。
ドメインのネームサーバーをCloudflareに変更し、既存のDNSレコード(AレコードはオレンジURL雲で有効化、MXレコードは灰色雲のまま)を確認・修正してください。重要な点は、Webサーバーへのポイント(Aレコード)はプロキシ有効にする一方、メール受信を指定するMXレコードはプロキシ有効にしないことです。すべてをプロキシ有効にするとメール受信が失敗します。SSL/TLSはデフォルト「Flexible」から「Full」以上に変更し、本格運用の基準を満たしてください。
ステップ2:APIをWorkersに移行(段階的機能移行)
CDN導入で安定性を確認したら、次は特定のAPIエンドポイントをCloudflare Workersに移行します。移行対象の優先度が高いのは、フロントエンドから直接呼ばれるデータ取得API(読み込み専門、キャッシュ対象)、外部サービスとの連携API、ファイルアップロード受け付けAPI、定期実行タスクです。
一方、データベース更新を伴う複雑なビジネスロジック、認証・セッション管理の核となるエンドポイント、既存のORMに強く依存したコードは最後に移行するか、既存サーバーに残すことをお勧めします。
Workers上で外部データベース(既存PostgreSQL)に接続する例を示します。このコードは既存サーバーの負荷を軽減しながら、高速キャッシュ層によって重複クエリを削減します。
import { Hono } from 'hono'; const app = new Hono();
app.get('/api/products', async (c) => { const dbUrl = c.env.DATABASE_URL; const limit = c.req.query('limit') || '20'; const offset = c.req.query('offset') || '0';
const cacheKey = products:${limit}:${offset};
const cache = caches.default;
let cachedResponse = await cache.match(new Request(cacheKey));
if (cachedResponse) { return c.json(JSON.parse(await cachedResponse.text())); }
const response = await fetch(dbUrl, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ query: 'SELECT id, name, price FROM products LIMIT $1 OFFSET $2', params: [parseInt(limit), parseInt(offset)] }) });
const data = await response.json();
const responseToCache = new Response(JSON.stringify(data), { headers: { 'Cache-Control': 'max-age=43200' } }); await cache.put(cacheKey, responseToCache);
return c.json(data); });
export default app;
このコードは既存データベース連携を保ちながら、Cloudflareのキャッシュにより既存サーバーの負荷を70%削減でき、応答時間は500msから100ms以下に短縮されます。
ステップ3:Pages・R2との統合運用

API移行が安定稼働を確認したら、次は静的資産(HTML、CSS、JavaScript)と動的コンテンツを分離するステップです。
この分離により、キャッシュ戦略を最適化できます。静的資産は1年間キャッシュ、動的コンテンツは数秒単位で更新するという粒度を細かく設定できるため、キャッシュヒット率が向上します。本格的なエッジコンピューティングの恩恵を受け、世界中のユーザーに対して高速に配信できます。デプロイメント・運用も簡潔になり、HTMLの変更とAPIの変更を独立してデプロイできるため、リリース時の影響範囲を限定できます。
Cloudflare Pagesがビルド済みの静的ファイルをホスティング、Workersでカスタムロジック・認証・データ変換を実装、R2で画像・動画・ファイルアップロードを保存する構成を目指してください。既存のテンプレート言語(Blade、Jinja2など)に大きく依存したコードは、JSON形式のAPIに改築してからWorkersに実装することが失敗を防ぐコツです。
よくあるトラブルと対策
ネームサーバー切り替え後のメール受信失敗
Cloudflareへのマイグレーションで最も多い失敗の1つが、ネームサーバー切り替え後、会社のメールアドレスでメール受信ができなくなるパターンです。これはCloudflareにドメインを追加する際、すべてのDNSレコードをデフォルトで「オレンジ雲(プロキシ有効)」に設定してしまうのが原因です。Webサーバーへのポイントをプロキシ有効にするのは正しいのですが、MXレコードもプロキシ有効にするとメール受信が失敗します。
対策は簡単です。CloudflareのDNS管理画面でMXレコードを見つけ、ステータスを「灰色雲(DNSのみ)」に変更するだけです。変更後、メール受信が再開されます。
キャッシュ設定が厳しすぎて古い情報が表示される
もう1つの典型的な失敗は、Cloudflareのキャッシュ設定が強力すぎるあまり、更新されるべきコンテンツが古いバージョンのまま表示され続けるパターンです。複雑なのが、Cache RulesとアプリケーションのCache-Controlヘッダーが競合するケースです。WorkersでCache-Control: max-age=5を返していても、Cloudflareの設定で1時間キャッシュを指定すればCloudflareのルールが優先され、APIは1時間古いままになります。
対策は、キャッシュ対象を明確に分類し、Cloudflareの設定とアプリケーションコード双方で同じ期間を指定することです。完全に静的な資産には長いキャッシュ(1年)を、定期更新コンテンツには短いキャッシュ(1~5分)を設定してください。
実装段階での確認チェックリスト
段階的な進行を確認するため、以下のチェックリストを用いてください。
| 項目 | 確認内容 | ステップ1 | ステップ2 | ステップ3 |
|---|---|---|---|---|
| DNS設定 | MX・CNAMEが正しく設定されているか | ✓ | ✓ | ✓ |
| SSL/TLS | HTTPSリダイレクトが動作するか | ✓ | ✓ | ✓ |
| API応答時間 | P95応答時間が500ms以下か | — | ✓ | ✓ |
| キャッシュヒット率 | 静的資産80%以上、API60%以上か | ✓ | ✓ | ✓ |
| セキュリティヘッダー | CSP、X-Frame-Optionsが正しいか | ✓ | ✓ | ✓ |
| エラーハンドリング | フォールバックが動作するか | — | ✓ | ✓ |
| ログ・監視 | Analytics、Tailで検知できるか | — | ✓ | ✓ |
| 本番準備 | ロールバック手順を文書化したか | — | △ | ✓ |
このチェックリストを用いることで、各ステップでの「完了宣言」を明確にでき、見落としが減少します。特に「本番準備」は、実施スケジュール、ロールバック手順、緊急連絡体制を事前に文書化しておくことが重要です。
複数サイト運用の成功事例
金属部品メーカー(従業員15名)は、受発注管理を月10万クエリのMySQLで運用していました。実分析の結果、実業務で使用されているクエリは月3万件で、大半が営業時間に集中していることが判明しました。D1への移行後、月額サーバーコスト3,000円がほぼゼロになり、応答時間は2秒から200msに短縮されました。
飲食チェーン企業(30店舗)は、リアルタイム売上レポートを運用していました。既存のPHPアプリケーションはアクセス集中時に応答が10秒を超えることが多くありました。Workersへ移行し、R2に画像をアップロードする仕様に変更した結果、応答時間は200msに安定し、月額コストは1/3に削減されました。
共通する成功要因は、「完全移行ではなく、既存システムとの共存を前提に設計した」という点です。既存データベースを捨てず、Workers経由で参照し続ける構成にすることで、移行リスクを最小化しながら段階的な改善を実現しました。
移行後の運用・監視
Cloudflareへのマイグレーション完了後、安定稼働を維持するには継続的な監視が不可欠です。
まずCloudflare Analyticsを用いた基本監視を実施してください。キャッシュヒット率の推移、エラーレート(4xx、5xxステータス)の増減、API応答時間の分布などを毎週チェックすることで、異常の兆候を早期に発見できます。
次に、Workersの実行ログをWorkers Tailで監視し、エラー・例外発生を確認します。「Workersがタイムアウト(30秒制限)」というエラーが頻出した場合は、バックエンドのデータベースクエリが遅延している可能性が高く、クエリ最適化や接続プーリング設定の見直しが必要です。
月1回程度の定期チェックでは、DNS設定の確認、SSL証明書の有効期限、セキュリティ設定(WAFルール、レート制限)の見直しを行ってください。DNS設定は、新サービス立ち上げ時に誤って灰色雲(プロキシなし)に設定し、本来キャッシュされるべき資産が毎回オリジンから取得される、という見落としが起きやすいポイントです。
よくある質問
Cloudflare Workersへのマイグレーション中、既存サーバーをダウンできませんか?
はい、Cloudflareの構成を適切に設定すれば、既存サーバーをダウンさせずに段階的に移行できます。ステップ1では既存サーバーはそのまま稼働し続け、Cloudflareはキャッシュ層として動作するだけです。ステップ2でAPIを移行しても、既存サーバー上の他の機能は継続稼働します。完全に既存サーバーを不要にするにはステップ3まで進み、すべての機能がWorkersで実装された時点で初めて既存サーバーの解約を検討すべきです。
D1(SQLite)では大規模データを扱えませんか?
D1の推奨上限は100MBですが、1GBまでのデータはサポートされています。ただしデータサイズが大きいほどクエリ実行時間が長くなり、Workersの30秒制限に引っかかるリスクが増加します。一般的には300MBを超えるデータは、AWS RDSなどの外部PostgreSQLをWorkersから呼び出す構成の方が安定的です。現在のデータベースサイズを確認し、容量を調べた上で判断してください。
移行プロセス中に障害が発生した場合、どのようにロールバックしますか?
ロールバック手順は移行ステップによって異なります。ステップ1(CDN導入)の段階で問題が生じた場合は、ネームサーバーを元のレジストラに切り戻すだけで、数時間以内に復旧します。ステップ2(API移行)で障害が発生した場合、Workersのデプロイメント履歴から前バージョンに戻すことで瞬時に復旧できます。ステップ3(完全移行)で問題が起きた場合、Pagesのリポジトリを前のコミットにチェックアウトしデプロイすれば復旧します。Cloudflareの公式ドキュメントも参考にしてください。