Cloudflare Workers 部署

适合带登录、支付、数据库的完整产品:计算(Workers)+ 数据库(D1)+ 静态资源 + 域名都在 Cloudflare 一家,免费额度大。codenav.cc 现在就跑在这套架构上。

前置准备

  • Cloudflare 账号,域名已添加为站点(NS 托管到 Cloudflare)
  • Node.js 18+,项目本地能 npm run build
  • 本教程以 Next.js 为例(其他框架用各自的 Workers 适配器,思路相同)

第一步:装链路并登录

npm i -D @opennextjs/cloudflare wrangler
npx wrangler login   # 浏览器弹出授权,点确认

项目根新建 wrangler.jsonc

{
  "name": "my-app",
  "main": ".open-next/worker.js",
  "compatibility_date": "2026-05-01",
  "compatibility_flags": ["nodejs_compat"],
  "assets": { "directory": ".open-next/assets", "binding": "ASSETS" },
  "workers_dev": true
}

再加一个 open-next.config.ts

import { defineCloudflareConfig } from "@opennextjs/cloudflare";
export default defineCloudflareConfig();

第二步:数据库(需要的话)

npx wrangler d1 create my-app-db --location apac   # apac = 离国内用户近

把输出的 database_id 填进 wrangler.jsonc

"d1_databases": [
  { "binding": "DB", "database_name": "my-app-db", "database_id": "粘贴这里", "migrations_dir": "drizzle" }
]

建表(以 drizzle 为例):npx drizzle-kit generate 生成迁移 SQL,然后:

npx wrangler d1 migrations apply my-app-db --local    # 本地库
npx wrangler d1 migrations apply my-app-db --remote   # 生产库

注意:D1 binding 只在请求上下文里可用。数据库/鉴权实例要懒初始化(首次访问时再创建),不要在模块顶层直接连。

第三步:密钥与构建部署

密钥不进代码、不进 .env 提交,用 secrets:

printf '%s' "$(openssl rand -base64 32)" | npx wrangler secret put AUTH_SECRET
printf '%s' "你的密钥" | npx wrangler secret put SOME_API_KEY

构建并部署:

# NEXT_PUBLIC_* 是构建期内联的,构建前确认 .env 里写的是正式域名
npx opennextjs-cloudflare build
npx wrangler deploy

部署完会得到 https://my-app.<你的子域>.workers.dev,先在这里验收功能。

第四步:绑定自己的域名

wrangler.jsonc 加路由后重新 npx wrangler deploy

"routes": [
  { "pattern": "xxx.com/*", "zone_name": "xxx.com" },
  { "pattern": "www.xxx.com/*", "zone_name": "xxx.com" }
]

然后到 Cloudflare DNS 给 @www 各加一条记录并开启橙云(Proxied)——内容随便填(如 A 192.0.2.1),流量实际由 Worker 路由接管。到这一步,全球访问已经通了。

第五步:国内优选(进阶,可选)

橙云直连用的是 Cloudflare 默认 anycast,国内速度一般。要更快,用 Cloudflare for SaaS 自定义主机名方案(实测可用,免费 100 个主机名):

  1. 准备一个辅助域名(任何闲置的、也托管在 Cloudflare 的域名)
  2. 给 Worker 绑一个辅助域接入点:routes 里加 { "pattern": "app.辅助域.com", "custom_domain": true }
  3. 辅助域 zone → SSL/TLS → Custom Hostnames:开通 SaaS($0/月),回退源填 app.辅助域.com,添加自定义主机名 xxx.comwww.xxx.com(TXT 验证,按提示在主域 DNS 加记录)
  4. 在辅助域 zone 上为主域名建 Worker 路由(xxx.com/* → 你的 Worker)
  5. 主域 DNS:@www 改为 灰云 CNAME → 优选域名(如 cf.090227.xyz,社区维护的国内低延迟 CF IP 集合)

坑一:「灰云 + Worker 路由」直接配是不生效的——Workers 路由要求记录橙云才执行,灰云流量会被透传到记录指向的目标。必须走 SaaS 自定义主机名,让边缘按 SNI 匹配。

坑二:换优选域名前,务必同时验证国内和海外两个视角的解析(阿里 DoH + 1.1.1.1)。部分社区优选域名只配了国内线路,海外解析为空——会导致 Googlebot 和海外用户彻底打不开。

坑三:用了 generateStaticParams 的 SSG 动态路由(如 /docs/[slug])部署后 404? OpenNext 默认没配增量缓存,预渲染产物找不到。在 open-next.config.ts 里加上:

import staticAssetsIncrementalCache from "@opennextjs/cloudflare/overrides/incremental-cache/static-assets-incremental-cache";
export default defineCloudflareConfig({ incrementalCache: staticAssetsIncrementalCache });

另外 Workers 运行时没有文件系统——运行时 fs.readFile 一律失败,构建期把内容烘焙进 JS。

验收清单

  • workers.dev 地址功能全通(注册/登录/核心流程)
  • https://你的域名 国内蜂窝网络实测可开
  • npx wrangler tail 能看到实时日志(排查线上问题用)
  • 数据库迁移已 apply 到 --remote

日常操作速查

npx opennextjs-cloudflare build && npx wrangler deploy   # 发版
npx wrangler tail                                        # 看生产日志
npx wrangler d1 execute my-app-db --remote --command "SELECT ..."  # 查生产库