基于 Cloudflare + OpenResty 的 Next.js 蓝绿部署实战(显式控制版)
·
在使用 Next.js(App Router + ISR)时,部署策略如果设计不当,很容易出现:
- ISR 缓存错乱
- buildId 不匹配
- 静态资源 404
- 无法快速回滚
本文介绍一种生产可用的蓝绿部署方案:
- 不修改域名
- 不修改 Nginx
- 不重启 Worker
- 秒级回滚
- 支持灰度发布
一、整体架构
以 us-east.example.com 为例:
User
↓
Cloudflare (Worker 注入版本头)
↓
us-east.example.com
↓
OpenResty
↓
next-blue :3001
next-green :3002
关键思想:
- 外部域名固定
- 内部运行两个版本
- 通过 Header 决定流量走向
- 蓝绿是流量槽位,而不是版本号
二、内部端口规划
推荐:
Blue → 3001
Green → 3002
Docker 启动方式:
docker run -d -p 127.0.0.1:3001:3000 --name next-blue next-image:blue
docker run -d -p 127.0.0.1:3002:3000 --name next-green next-image:green
注意:
- 仅绑定 127.0.0.1
- 不暴露公网
- 所有流量由 OpenResty 统一代理
三、OpenResty 蓝绿配置
1️⃣ 使用 map 计算 backend
map $http_x_version $backend {
default blue;
green green;
}
含义:
- 请求头
x-version: green→ 走 green - 其他情况 → 默认 blue
2️⃣ 定义 upstream
upstream blue {
server 127.0.0.1:3001;
}
upstream green {
server 127.0.0.1:3002;
}
upstream 是后端服务器组定义。
当执行:
proxy_pass http://green;
Nginx 会将请求转发到 127.0.0.1:3002。
3️⃣ server 代理
server {
listen 443 ssl;
server_name us-east.example.com;
location / {
proxy_pass http://$backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
关键在:
proxy_pass http://$backend;
$backend 由 map 动态决定。
四、Cloudflare Worker 显式控制蓝绿
错误做法(不推荐):
const versionColor =
versionKey === "2026-02-26" ? "green" : "blue"
问题:
- 强耦合版本号
- 每次发版要改代码
- 回滚需要重新发布 Worker
✅ 正确做法:KV 显式存储当前颜色
KV 结构:
current_color = green
Worker 代码:
const versionColor =
(await KV.get("current_color")) || "blue"
request = new Request(request, {
headers: {
...Object.fromEntries(request.headers),
"x-version": versionColor,
},
})
发布流程变成:
部署 green
↓
KV 设置 current_color = green
↓
流量自动切换
回滚:
KV 改回 blue
无需改代码。
五、蓝绿与版本解耦
更工程化设计:
{
"blue": "build-2026-02-20",
"green": "build-2026-02-26",
"current": "green"
}
说明:
- blue / green 是固定流量槽位
- 版本号只是绑定关系
- current 决定当前流量走向
蓝绿不是版本。
蓝绿是“发布位置”。
六、完整发布流程
假设当前:
3001 (blue) → 正在线上
3002 (green) → 空闲
发版流程:
- 构建新镜像
- 部署到 green (3002)
- 本地验证
- 修改 KV → current_color = green
- 全量流量切换
- 保留 blue 作为回滚
整个过程:
- 无需重启 Nginx
- 无需修改 Worker
- 无需改域名
七、进阶:支持灰度发布
KV:
{
"stable": "blue",
"canary": "green",
"ratio": 10
}
Worker:
const config = await KV.get("deploy_config", "json")
let versionColor = config.stable
if (Math.random() * 100 < config.ratio) {
versionColor = config.canary
}
即可实现 10% 灰度。
八、为什么这种设计更优?
优势总结:
- 版本与流量解耦
- 发布无需改代码
- 回滚秒级完成
- 可扩展灰度发布
- 结构清晰
核心思想:
代码不控制版本,配置控制流量。
九、总结
在 Cloudflare + Next.js ISR 场景下:
最佳蓝绿方案是:
- 双容器运行
- OpenResty 使用 map + upstream
- Worker 注入 x-version
- KV 显式控制当前颜色
- 蓝绿与版本解耦
最终效果:
- 零停机发布
- 秒级回滚
- 可灰度
- 可扩展
更多推荐



所有评论(0)