1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Cloudflare PagesからWorkersへの移行ガイド(2026年版)

1
Last updated at Posted at 2026-03-23

CloudflareはPagesをWorkersに統合しつつある。Pagesが明日なくなるわけではないが、新機能はすべてWorkers側にのみ追加されている。筆者は2026年初頭に全PagesプロジェクトをWorkersへ移行し、その過程でつまずいたポイントをまとめた。

本記事はcogley.jpの完全版の要約版です。各機能の詳細な解説、CI/CDの全パターン、トラブルシューティングツリーなどは完全版をご覧ください。

PagesとWorkersの機能比較

Workersテックリードの Kenton Varda 氏は「Pages固有の機能をすべて汎用的なWorkers機能に変えていく」と述べている。公式の互換性マトリクスを見ると、差は拡大し続けている。

機能 Pages Workers
静的アセット / SSR
Durable Objects 別途Workerが必要 ネイティブ対応
Cronトリガー
Queue Consumer
Email Workers(受信)
画像リサイズバインディング
レート制限
Workers Logs 基本のみ フルオブザーバビリティ
Tail Workers / ソースマップ
段階的デプロイ
Smart Placement / Secrets Store

移行プロセス概要

設定の変換

Pages設定:

{
  "name": "my-project",
  "pages_build_output_dir": "./dist/client/",
}

Workers設定:

{
  "name": "my-project",
  "compatibility_date": "2026-03-01",
  "compatibility_flags": ["nodejs_compat"],
  "main": "./dist/server/index.js",
  "assets": {
    "directory": "./dist/client/",
    "binding": "ASSETS",
    "not_found_handling": "single-page-application",
  },
}

主な変更点:

  • pages_build_output_dirassets.directory
  • main でサーバーエントリポイントを指定
  • compatibility_date を追加(必須)
  • compatibility_flags: ["nodejs_compat"] でNode.js APIポリフィルを有効化
  • 404ハンドリングを明示的に設定

静的サイトの場合

{
  "name": "my-static-site",
  "compatibility_date": "2026-03-01",
  "assets": {
    "directory": "./dist/",
    "not_found_handling": "404-page",
  },
}

.assetsignore の作成

Pagesは node_modules 等を自動除外していたが、Workersでは明示的に指定する。

node_modules
.git
.DS_Store
.env*
*.map

SvelteKitで @sveltejs/adapter-cloudflare を使う場合は、アダプタが自動処理するため通常不要。

SvelteKit移行

アダプタを更新する。

npm install -D @sveltejs/adapter-cloudflare

svelte.config.js:

import adapter from '@sveltejs/adapter-cloudflare';

export default {
  kit: {
    adapter: adapter({
      routes: {
        include: ['/*'],
        exclude: ['<all>'],
      },
      platformProxy: {
        configPath: './wrangler.jsonc',
        persist: { path: '.wrangler/state/v3' },
      },
    }),
  },
};

wrangler.jsonc:

{
  "name": "my-sveltekit-app",
  "compatibility_date": "2026-03-01",
  "compatibility_flags": ["nodejs_compat"],
  "main": ".svelte-kit/cloudflare/_worker.js",
  "assets": {
    "directory": ".svelte-kit/cloudflare",
    "binding": "ASSETS",
  },
  "workers_dev": true,
  "preview_urls": true,
}

注意: @sveltejs/adapter-cloudflare の出力先は .svelte-kit/cloudflare/ であり、./dist/ ではない。パスを間違えると「Worker not found」エラーになる。

バインディングへのアクセスは platform.env 経由:

// +page.server.ts
export async function load({ platform }) {
  const db = platform?.env?.DB;
  const result = await db?.prepare('SELECT * FROM posts').all();
  return { posts: result?.results ?? [] };
}

ドメイン移行:最も難しいポイント

カスタムドメインの移行が単純でない理由:

  1. ドメインがPagesに紐づいている間は、Workersにドメインを追加できない
  2. Pagesから先に削除するとダウンタイムが発生する

解決策はAPIによるアトミックな切り替えだ。

アトミックなドメイン切り替えスクリプト

#!/bin/bash
set -e

ACCOUNT_ID="your-account-id"
ZONE_ID="your-zone-id"
API_TOKEN="your-api-token"
PAGES_PROJECT="old-pages-project"
WORKERS_SCRIPT="new-workers-project"
DOMAIN="yourdomain.com"

echo "Removing domain from Pages..."
curl -s -X DELETE \
  "https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/pages/projects/${PAGES_PROJECT}/domains/${DOMAIN}" \
  -H "Authorization: Bearer ${API_TOKEN}"

echo "Adding Workers route for root domain..."
curl -s -X POST \
  "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/workers/routes" \
  -H "Authorization: Bearer ${API_TOKEN}" \
  -H "Content-Type: application/json" \
  --data '{
    "pattern": "'"${DOMAIN}"'/*",
    "script": "'"${WORKERS_SCRIPT}"'"
  }'

echo "Adding Workers route for www subdomain..."
curl -s -X POST \
  "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/workers/routes" \
  -H "Authorization: Bearer ${API_TOKEN}" \
  -H "Content-Type: application/json" \
  --data '{
    "pattern": "www.'"${DOMAIN}"'/*",
    "script": "'"${WORKERS_SCRIPT}"'"
  }'

echo "Done! Domain switched to Workers."

ダウンタイムは2〜5秒程度。切り替え後は両ドメインのテストと「Always Use HTTPS」の有効化を忘れずに。

Workers移行後に使える主な機能

Service Bindings

ネットワークオーバーヘッドなしで複数Workerを接続。トラフィックはCloudflareのネットワーク内にとどまる。

{
  "services": [
    {
      "binding": "AUTH_SERVICE",
      "service": "auth-worker",
    },
  ],
}

D1リードレプリケーション

リードレプリカ使用時はD1 Sessionsでread-after-write整合性を確保する。

// セッションを使わないと書き込み直後に古いデータを読む可能性あり
const db = env.DB.withSession();
await db.prepare('INSERT INTO posts (title) VALUES (?)').bind('New Post').run();
const posts = await db.prepare('SELECT * FROM posts').all(); // 確実にinsertが含まれる

オブザーバビリティ

{
  "observability": {
    "enabled": true,
    "head_sampling_rate": 1,
    "logs": { "enabled": true, "head_sampling_rate": 1, "invocation_logs": true },
    "traces": { "enabled": true, "head_sampling_rate": 1 },
  },
}

よくあるトラブルと対処法

症状 原因 対処法
fs/path/process エラー nodejs_compat フラグ未設定 compatibility_flags に追加
522タイムアウト 誤ったCNAME設定 Workers routesを使用
ルートで404 not_found_handling 未設定 single-page-application404-page を設定
認証失敗 シークレット未同期 wrangler secret put で再設定
バンドルサイズ超過 10MB制限 Vite 8へアップグレード、ダイナミックインポート
エラー10021 Secrets Store権限不足 トークンにEdit権限を追加
Pages削除不可 デプロイ500件超 APIでバッチ削除

移行後チェックリスト

  • 全カスタムドメインでサイトが正しく読み込まれる
  • ルートとwwwの両方が動作する
  • HTTPSが強制されている
  • 環境変数とシークレットが設定済み
  • データベースバインディング(D1、KV、R2)が動作する
  • オブザーバビリティ/ログが有効
  • CI/CDが正常にデプロイする

まとめ

2026年3月時点で、WorkersはPagesの全機能をカバーしている。強制移行の期限は未発表だが、新機能の差は広がり続けている。新規プロジェクトはWorkersで始めるべきだ。既存Pagesプロジェクトは、自分のスケジュールでコントロールできるうちに移行するのがよい。

ドメイン切り替え以外はすべて設定変更のみで、ドメイン切り替えも上記のアトミックAPIアプローチで2〜5秒のダウンタイムに抑えられる。


参考資料:


この記事は cogley.jp に掲載されたものです。

Rick Cogley(コグレー・リック)株式会社イソリアのCEO兼創業者。東京で日英バイリンガルITアウトソーシングとインフラサービスを提供中。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?