Menu

使用 CloudFlare Workers 部署 Next.js 项目

Vercel 是开发者体验最棒的部署平台,但网站有流量后成本很容易飙升;Dokploy 和 Coolify 是最好的 VPS 托管工具,仅需购买一台 VPS 就能无限部署,但你需要自己确保 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 的部署教程。

第一步:配置 CLI 环境

在开始配置之前,请确保你已经安装了 wrangler(Cloudflare 的命令行工具),并完成账号登录。

在终端执行以下命令:

npx wrangler login

执行后会自动打开浏览器,完成授权即可。这是后续所有 R2、D1 和部署操作的前提。

第二步:创建 wrangler.jsonc

这是模板 cf-pg 分支自带的 wrangler.example.jsonc

{
	"$schema": "node_modules/wrangler/config-schema.json",
	"name": "<YOUR_WORKER_APP_NAME>",
	"main": ".open-next/worker.js",
	// When you start your project, you should always set compatibility_date to the current date
	// https://developers.cloudflare.com/workers/configuration/compatibility-dates/
	"compatibility_date": "2026-02-22",
	"compatibility_flags": [
		"nodejs_compat",
		"global_fetch_strictly_public"
	],
	// Your Cloudflare Account ID: Cloudflare Dashboard → Workers & Pages → Overview → Account ID
	"account_id": "<YOUR_ACCOUNT_ID>",
	"assets": {
		"directory": ".open-next/assets",
		"binding": "ASSETS"
	},
	"services": [
		{
			// Required by @opennextjs/cloudflare for ISR/revalidation
			"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) ---
	// Required for ISR/SSG caching
	"r2_buckets": [
		{
			"binding": "NEXT_INC_CACHE_R2_BUCKET",
			"bucket_name": "<YOUR_BUCKET_NAME>"
		}
	],
	// --- Queue (Durable Objects) ---
	// Required for time-based revalidation (ISR)
	"durable_objects": {
		"bindings": [
			{
				"name": "NEXT_CACHE_DO_QUEUE",
				"class_name": "DOQueueHandler"
			}
		]
	},
	"migrations": [
		{
			"tag": "v1",
			"new_sqlite_classes": [
				"DOQueueHandler"
			]
		}
	],
	// --- Tag Cache (D1) ---
	// Required for On-demand revalidation (revalidatePath/revalidateTag)
	// Create D1 database: npx wrangler d1 create <YOUR_D1_DATABASE_NAME>
	// Then update the database_id below
	"d1_databases": [
		{
			"binding": "NEXT_TAG_CACHE_D1",
			"database_name": "<YOUR_D1_DATABASE_NAME>",
			"database_id": "<YOUR_D1_DATABASE_ID>"
		}
	],
  // Use Hyperdrive for TCP-based PostgreSQL connections (Supabase, Self-hosted, or Neon via TCP).
  // You can omit this if using provider-specific HTTP drivers (e.g., @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 端口的连接串。

第三步:自动部署与配置

无论使用 Neon 还是 Supabase,这一步操作都是一样的。

创建项目、Deploy

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

这里还有运行时环境变量,页面上只能一个个手动添加,但是模板内置了脚本,你只需要执行 node scripts/sync-env-to-cloudflare.mjs .env,就能把 .env 里面的环境变量提交到 Workers。可以指定你要迁移的环境变量文件,即 .env 可以改成 .env.local

因为在 Build 环境变量里添加了 NEXT_PUBLIC_ 环境变量了,所以运行时环境变量无需添加 NEXT_PUBLIC_ 环境变量。

更新完环境变量,重新构建,可以推送代码触发构建,也可以在 Developments 里面找到最新的构建记录,点击 Retry Build。

现在打开你的自定义域名就能访问了。