本指南详细介绍了如何将一个 Next.js 项目,通过 OpenNext 编译并利用 GitHub Actions 自动化部署到 Cloudflare Workers 的完整流程,同时总结了开发和部署中常见的避坑指南。
目录
1. 项目准备与本地配置
在 Cloudflare 部署 Next.js,目前最稳定且推荐的方式是使用 @opennextjs/cloudflare。它能够将 Next.js 的全栈能力(包括 ISR, SSR, App Router)转换并适配到 Cloudflare Worker 架构中。
1.1 安装依赖
在项目根目录运行以下命令安装所需依赖:
npm install @opennextjs/cloudflare
npm install --save-dev wrangler
1.2 配置文件 wrangler.jsonc
在项目根目录下创建 [wrangler.jsonc],用于定义 Worker 的基础配置和静态资源绑定:
{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "your name", // 部署在 Cloudflare 上的项目名称
"main": ".open-next/worker.js", // OpenNext 编译后的入口文件
"compatibility_date": "2024-09-23", // 兼容性日期
"compatibility_flags": [
"nodejs_compat" // 启用 Node.js 兼容性 API(核心,必填)
],
"assets": {
"directory": ".open-next/assets", // 静态资源目录
"binding": "ASSETS"
}
}
2. 本地预览与编译命令
在项目的 [package.json]中,推荐配置如下构建与部署脚本:
"scripts": {
"dev": "next dev -p 3010 --webpack",
"build": "next build --webpack",
"build:cf": "opennextjs-cloudflare build",
"deploy": "opennextjs-cloudflare build && opennextjs-cloudflare deploy",
"preview": "opennextjs-cloudflare build && wrangler dev"
}
-
npm run build:cf:专门针对 Cloudflare 环境进行 OpenNext 构建,生成位于.open-next/目录的资源。 -
npm run preview:在本地模拟 Cloudflare 运行环境,并使用 Wrangler 预览打包后的项目,推荐在部署前运行此命令自测。
3. Cloudflare 凭证准备与获取
自动化部署需要 GitHub Actions 能够代表您向 Cloudflare 推送代码,因此需要在 GitHub 仓库中配置相应的 API 凭证。
3.1 获取 CLOUDFLARE_ACCOUNT_ID
- 登录到 Cloudflare Dashboard。
- 选中您部署的目标账户,进入首页。
- 在页面右侧导航栏中找到 账户 ID (Account ID)(或url上)。
- 复制该 32 位字符并保存。
3.2 创建 CLOUDFLARE_API_TOKEN
- 登录 Cloudflare 后,找到左侧管理账户。
- 点击 账户 API 令牌 (API Tokens),右上角 创建令牌 (Create Token)。
- 名称自定义,权限策略选择自定义(建议Edit Cloudflare Workers)
-
权限范围配置建议:
- 账户资源:选择“整个账户”或指定具体的目标账户。
- 令牌过期时间:建议选择 “无过期时间”,避免因 Token 到期导致后续 GitHub Pipeline 意外中断。
- 点击“审核令牌”,确认无误后点击“创建令牌”。
- 复制并保存生成的 Token 值(注意:该 Token 仅展示一次,离开页面后将无法再次查看)。
3.3 将凭证添加到 GitHub Secrets
- 打开您的 GitHub 代码仓库页面。
- 依次点击 Settings -> Secrets and variables -> Actions。
- 点击 New repository secret,添加以下两个 Secret:
-
Secret 1:
-
Name:
CLOUDFLARE_ACCOUNT_ID - Value: [您获取的 Account ID]
-
Name:
-
Secret 2:
-
Name:
CLOUDFLARE_API_TOKEN - Value: [您生成的 API Token]
-
Name:
-
Secret 1:
4. GitHub Actions 自动化工作流配置
在项目根目录下,创建目录及文件 [.github/workflows/deploy.yml]。
name: Deploy to Cloudflare Workers
on:
push:
branches:
- main # 当且仅当向 main 分支推送代码时触发部署
jobs:
deploy:
runs-on: ubuntu-latest
name: Deploy
steps:
# 1. 检出代码
- name: Checkout repository
uses: actions/checkout@v4
# 2. 安装 Node 环境并开启缓存加速
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
# 3. 安装依赖(使用 ci 确保依赖版本的一致性)
- name: Install dependencies
run: npm ci
# 4. 执行 OpenNext 针对 Cloudflare 的构建
- name: Build for Cloudflare
run: npm run build:cf
# 5. 执行 Wrangler 自动化发布
- name: Deploy to Cloudflare Workers
uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: deploy
5. 🔴 核心避坑指南 (重要问题点)
在配置 Cloudflare 自动部署时,以下几点是开发者最常踩的坑,请务必注意:
5.1 构建时(Build-time)与运行时(Runtime)环境变量
这是 Next.js 部署中最容易出错的一点。
-
问题背景:以
NEXT_PUBLIC_开头的环境变量会被 Next.js 在构建打包(Compilation)阶段直接硬编码替换进前端客户端 JS 资源中。 -
为什么
.env.local失效:由于.env.local默认在.gitignore中被忽略,GitHub Actions 拉取代码时没有该文件,导致打包出来的 JS 资源中 API 地址为空。 -
解决方案:
-
方法 A(适合公开 URL):创建
.env.production文件配置 API 地址,并随 Git 提交。Next.js 在构建阶段会自动读取该文件。 -
方法 B(更灵活/推荐):在 GitHub 仓库的 Settings -> Secrets and variables -> Actions -> Variables 中新增一个 Repository Variable(例如
NEXT_PUBLIC_API_BASE_URL),然后修改 [deploy.yml]在打包步骤注入:- name: Build for Cloudflare env: NEXT_PUBLIC_API_BASE_URL: ${{ vars.NEXT_PUBLIC_API_BASE_URL }} run: npm run build:cf
-
方法 A(适合公开 URL):创建
- ⚠️ 特别注意:在 Cloudflare Dashboard 的 Workers Settings 中配置的环境变量(即运行时变量),只对服务器端(SSR/API Routes)代码有效,对于浏览器端执行的代码是无法通过运行时获取到的。
5.2 兼容性标志 (compatibility_flags)
由于 Next.js 运行在 Cloudflare Workers 上,它默认使用的是 V8 Isolate 边缘环境,而不是标准的 Node.js 容器。
-
问题点:Next.js 或某些第三方库依赖 Node.js 原生 API(如
Buffer,crypto,events等)。如果不启用兼容支持,构建或运行时会抛出找不到模块的错误。 -
解决方案:必须在
wrangler.jsonc中配置"compatibility_flags": ["nodejs_compat"],以便让 Cloudflare 的边缘环境模拟提供 Node 核心 API。
5.3 触发分支的命名不一致
- 许多代码仓库默认主分支依然是
master,但有些新项目默认为main。 - 编写
deploy.yml时,需确认on.push.branches部分匹配您的实际默认分支。如果实际为master,请记得修改配置。