Menu

CloudFlare Workersを使用したNext.jsプロジェクトのデプロイ

Vercelは開発者体験が最高のデプロイプラットフォームですが、サイトにトラフィックが発生すると簡単にコストが高騰します。DokployとCoolifyは最高のVPSホスティングツールで、VPSを1台購入するだけで無制限にデプロイできますが、VPSのセキュリティは自分で確保する必要があります。

CloudFlare Workersは月額わずか$5の基本サブスクリプション料金でサービスを提供しており、月間1,000万回の無料リクエストと3,000万ミリ秒のCPU実行時間が含まれているため、Vercelと比較して非常にコストパフォーマンスが高く、CloudFlare Workersへのデプロイを試みる人が増えています。

ただし、CloudFlare Workersにも欠点がないわけではありません。デプロイ体験が非常に不親切で、大量のドキュメントとコミュニティの経験を読んで初めてデプロイに成功できます。

NEXTY.DEVテンプレートはCloudFlare Workersのデプロイ要件に対応するため、独立したcf-pgブランチを作成し、CloudFlare Workers + Postgresのデプロイに特化して対応しています。

このブランチはCloudFlare Workers上でNeon、Supabase、セルフホストPostgresの使用をサポートしています。

本記事はNEXTY.DEVテンプレートのcf-pgブランチをCloudFlare Workersにデプロイするチュートリアルです。

ステップ1:CLI環境の設定

設定を始める前に、wrangler(Cloudflareのコマンドラインツール)がインストールされており、アカウントログインが完了していることを確認してください。

ターミナルで以下のコマンドを実行します:

npx wrangler login

実行するとブラウザが自動的に開き、認証を完了できます。これは、後続のすべてのR2、D1、およびデプロイ操作の前提条件です。

ステップ2:wrangler.jsoncの作成

これはテンプレートのcf-pgブランチに付属しているwrangler.example.jsoncです:

{
	"$schema": "node_modules/wrangler/config-schema.json",
	"name": "<YOUR_WORKER_APP_NAME>",
	"main": ".open-next/worker.js",
	// プロジェクトを開始する際は、常にcompatibility_dateを現在の日付に設定してください
	// https://developers.cloudflare.com/workers/configuration/compatibility-dates/
	"compatibility_date": "2026-02-22",
	"compatibility_flags": [
		"nodejs_compat",
		"global_fetch_strictly_public"
	],
	// あなたのCloudflare Account ID: Cloudflare Dashboard → Workers & Pages → Overview → Account ID
	"account_id": "<YOUR_ACCOUNT_ID>",
	"assets": {
		"directory": ".open-next/assets",
		"binding": "ASSETS"
	},
	"services": [
		{
			// @opennextjs/cloudflareのISR/再検証に必要
			"binding": "WORKER_SELF_REFERENCE",
			"service": "<YOUR_WORKER_APP_NAME>"
		}
	],
	"images": {
		"binding": "IMAGES"
	},
	"observability": {
		"logs": {
			"enabled": true,
			"invocation_logs": true
		}
	},
	"vars": {
		"DEPLOYMENT_PLATFORM": "cloudflare"
	},
	// --- Incremental Cache (R2) ---
	// ISR/SSGキャッシングに必要
	"r2_buckets": [
		{
			"binding": "NEXT_INC_CACHE_R2_BUCKET",
			"bucket_name": "<YOUR_BUCKET_NAME>"
		}
	],
	// --- Queue (Durable Objects) ---
	// 時間ベースの再検証(ISR)に必要
	"durable_objects": {
		"bindings": [
			{
				"name": "NEXT_CACHE_DO_QUEUE",
				"class_name": "DOQueueHandler"
			}
		]
	},
	"migrations": [
		{
			"tag": "v1",
			"new_sqlite_classes": [
				"DOQueueHandler"
			]
		}
	],
	// --- Tag Cache (D1) ---
	// オンデマンド再検証(revalidatePath/revalidateTag)に必要
	// D1データベースの作成: npx wrangler d1 create <YOUR_D1_DATABASE_NAME>
	// その後、以下のdatabase_idを更新してください
	"d1_databases": [
		{
			"binding": "NEXT_TAG_CACHE_D1",
			"database_name": "<YOUR_D1_DATABASE_NAME>",
			"database_id": "<YOUR_D1_DATABASE_ID>"
		}
	],
  // TCPベースのPostgreSQL接続(Supabase、セルフホスト、またはTCP経由のNeon)にはHyperdriveを使用してください。
  // プロバイダー固有のHTTPドライバー(@neondatabase/serverlessなど)を使用する場合は、これを省略できます。
	"hyperdrive": [
		{
			"binding": "HYPERDRIVE",
			"id": "<YOUR_HYPERDRIVE_ID>",
			"localConnectionString": "<YOUR_POOLER_CONNECTION_STRING>"
		}
	]
}

これをコピーしてwrangler.jsoncという名前で保存し、以下のパラメータをカスタマイズする必要があります:

  1. name: カスタマイズ

  2. compatibility_date: プロジェクト作成時の日付を入力

  3. account_id: Cloudflare Dashboard → Workers & Pages → Overview → Account IDからコピー

  4. WORKER_SELF_REFERENCE service: nameフィールドと同じ値を入力

  5. NEXT_INC_CACHE_R2_BUCKET bucket_name:

コマンドラインでnpx wrangler r2 bucket create <YOUR_BUCKET_NAME>を実行し、<YOUR_BUCKET_NAME>をカスタマイズした名前に置き換えます。作成後にbucket_nameが生成されるので、ファイルにコピーしてください。bindingは変更しないでください。

  1. d1_databases:

コマンドラインでnpx wrangler d1 create <YOUR_D1_DATABASE_NAME>を実行し、<YOUR_D1_DATABASE_NAME>をカスタマイズした名前に置き換えます。作成後にdatabase_namedatabase_idが生成されるので、ファイルにコピーしてください。bindingは変更しないでください。

  1. hyperdrive:

Neonを使用する場合は、hyperdriveの設定をコメントアウトしてください。Neonはサーバー側ですでにプロキシを設定しており、Serverless環境向けに特別に最適化されている(@neondatabase/serverlessを使用)ため、TCP接続の制限を回避できます。

SupabaseまたはセルフホストPostgresを使用する場合、これらは標準的なPostgresサービスであり、接続数の制限を受け、TCP接続の遅延も比較的長いため、Hyperdriveを有効にする必要があります。以下の手順に従って設定してください:

a. Hyperdriveの作成: CFコンソールのWorkers & Pages → Hyperdriveでインスタンスを作成します。

create-hyperdrive
create-hyperdrive

b. Supabaseの設定: 5432ポートの直接接続文字列をコピーします。これは、Hyperdrive自体が接続プールであり、Supabaseの6543ポートも接続プールであるため、接続プールに接続プールをマウントすると非常に不安定になるためです。

connect-string

直接接続文字列をHyperdriveに貼り付け、Enable cachingのチェックを外します

create-hyperdrive

c. IDのバインド: 生成されたHyperdrive IDをwrangler.tomlに入力します。

create-hyperdrive

d. ローカル開発: localConnectionStringに6543ポートの接続文字列を入力し、環境変数DATABASE_URLも6543ポートの接続文字列を使用します。

ステップ3:自動デプロイと設定

NeonまたはSupabaseのどちらを使用する場合でも、この手順の操作は同じです。

プロジェクトの作成とデプロイ

create-application

Project Nameはwrangler.jsoncnameフィールドと同じにする必要があります

create-application

最初のビルドは必ず失敗しますが、心配する必要はありません。

Settingsに入り、まず最下部までスクロールして、Github設定を変更します:

  • すべての本番環境の環境変数を追加します。この手順は手動でのみ実行できます。NEXT_PUBLIC_で始まる環境変数は直接追加し、その他の環境変数はEncryptボタンをクリックして暗号化します。環境変数を追加する際は、引用符をコピーしないでください。
  • Build cacheをDisabledに設定します
create-application

プロジェクトに複数のブランチがあり、特定のブランチのみでビルドをトリガーしたい場合は、Branch controlを変更し、Builds for non-production branchesのチェックを外してから、ブランチコードをプッシュします。

create-application

次にページの最上部までスクロールし、Domains & Routesでドメインを追加します

create-application

ここにはランタイム環境変数もありますが、ページ上では1つずつ手動で追加する必要があります。しかし、テンプレートには組み込みのスクリプトがあり、node scripts/sync-env-to-cloudflare.mjs .envを実行するだけで、.env内の環境変数をWorkersに送信できます。移行したい環境変数ファイルを指定できます。つまり、.env.env.localに変更できます。

Build環境変数にNEXT_PUBLIC_環境変数をすでに追加しているため、ランタイム環境変数にNEXT_PUBLIC_環境変数を追加する必要はありません。

環境変数を更新した後、再ビルドします。コードをプッシュしてビルドをトリガーすることも、Developmentsで最新のビルド記録を見つけてRetry Buildをクリックすることもできます。

これで、カスタムドメインを開いてアクセスできるようになりました。