部署指南
上线前检查、部署方式选择、环境变量、数据库迁移和部署后验证。
项目是 pnpm monorepo,应用在 apps/01mvp-web 下。
默认生产路径是 Zeabur + Cloudflare。Zeabur 运行 Next.js Docker 服务,Cloudflare 负责域名代理、HTTPS、WAF 和基础访问统计。
部署方式选择
| 方式 | 适合场景 | 入口 |
|---|---|---|
| Zeabur | 默认生产部署,适合 Next.js Docker 服务、数据库和域名统一管理 | Zeabur 部署 |
| Docker | 自有 VPS、K8s,或需要手动维护容器运行时 | Docker 部署 |
| Cloudflare Workers | 明确要把 Next.js 适配到 Workers,并愿意处理兼容性验证 | Cloudflare Workers 部署 |
| Vercel | 需要 Vercel Preview Deployment 或团队已经绑定 Vercel 流程 | Vercel 部署 |
Zeabur 部署
01MVP 默认部署路径,包含 Agent Skills 部署流程、环境变量、Docker、数据库和 Cloudflare 代理。
Zeabur Agent Skills
Zeabur Agent Skills 能力参考:安装、能力清单、常见场景和排错。
Docker 部署
用 Dockerfile 部署到自有服务器或容器平台。
Cloudflare Workers 部署
基于 OpenNext 的可选部署路径,适合明确需要 Workers 运行时的项目。
Vercel 部署
可选部署路径,适合依赖 Vercel Preview 和团队协作流的项目。
部署前检查清单
在触发任何部署之前,逐项确认以下内容:
- 本地
pnpm build构建成功,无 TypeScript 错误 -
pnpm db:status确认所有 migration 已提交到 Git -
.env.prd或生产变量源中的必填变量已同步到 Zeabur -
BETTER_AUTH_URL和NEXT_PUBLIC_SITE_URL指向生产域名 - OAuth 回调 URL 已在第三方平台更新为生产域名
- 数据库连接串可从部署平台网络访问
- S3 存储桶权限已配置
- AI API Key 有效且余额充足
- 支付 Webhook 地址已配置为生产域名
- 邮件服务 API Key 已配置
- Turnstile 已开启,认证高风险入口能完成人机验证
- Cloudflare WAF/DDoS 规则已配置
环境变量管理
多环境策略
01MVP 项目使用以下环境文件管理本地开发变量:
| 文件 | 用途 | 是否提交到 Git |
|---|---|---|
.env.example | 变量模板,列出所有变量名和说明 | 是 |
.env.local | 本地开发变量,包含真实密钥 | 否 |
.env.prd | 本地模拟生产环境时使用 | 否 |
必填变量
| 变量名 | 说明 | 示例 |
|---|---|---|
DATABASE_URL | PostgreSQL 连接串 | postgresql://user:pass@host:5432/prod |
BETTER_AUTH_SECRET | Auth 签名密钥 | 随机生成的强密钥 |
BETTER_AUTH_URL | Auth 回调基础 URL | https://your-domain.com |
NEXT_PUBLIC_SITE_URL | 站点公开 URL | https://your-domain.com |
OPENAI_API_KEY | AI API 密钥 | sk-... |
按需变量
| 类型 | 变量 |
|---|---|
| S3 存储 | S3_ENDPOINT、S3_REGION、S3_ACCESS_KEY_ID、S3_SECRET_ACCESS_KEY、S3_BUCKET、NEXT_PUBLIC_S3_ENDPOINT |
| OAuth 登录 | GOOGLE_CLIENT_ID、GOOGLE_CLIENT_SECRET、GITHUB_CLIENT_ID、GITHUB_CLIENT_SECRET、WECHAT_WEBSITE_APP_ID、WECHAT_WEBSITE_APP_SECRET |
| 支付 | STRIPE_SECRET_KEY、STRIPE_WEBHOOK_SECRET、NEXT_PUBLIC_STRIPE_PRICE_PRO_MONTHLY、NEXT_PUBLIC_STRIPE_PRICE_PRO_YEARLY、WAFFO_MERCHANT_ID、WAFFO_PRIVATE_KEY |
| 邮件 | RESEND_API_KEY、ZEABUR_EMAIL_API_KEY、EMAIL_FROM、CONTACT_EMAIL |
| 统计与安全 | NEXT_PUBLIC_UMAMI_WEBSITE_ID、NEXT_PUBLIC_UMAMI_SCRIPT_URL、NEXT_PUBLIC_GOOGLE_ANALYTICS_ID、EDGE_WAF_PROVIDER、EDGE_WAF_CONFIGURED |
敏感变量只在部署平台设置,不要提交到 Git。NEXT_PUBLIC_ 前缀变量会进入客户端 bundle,只放公开信息。
数据库迁移策略
迁移原则
生产数据库变更必须使用 migration。不要在生产环境运行 pnpm db:push:unsafe,也不要用 Drizzle Studio 手动改表结构。
迁移工作流
开发阶段创建迁移
修改 apps/01mvp-web/src/db/schema 后,创建迁移文件:
pnpm db:generate这会在 apps/01mvp-web/drizzle 下生成 SQL 文件。
提交迁移文件
将生成的 migration 文件提交到 Git,例如 apps/01mvp-web/drizzle/0001_add_ai_media_task.sql。
部署前执行生产迁移
在目标数据库执行已提交的迁移:
pnpm db:deploydb:deploy 不会创建新迁移,只执行已提交但未应用的迁移。
验证迁移状态
pnpm db:status确认没有 pending migration 后再触发应用部署。
生产环境怎么执行迁移
生产迁移的关键不是命令本身,而是确认命令连接的是生产数据库。推荐在应用部署前单独执行,不要把迁移塞进 Next.js build 或运行时启动脚本。
适合小团队和第一次上线。不要依赖本地 .env.local,直接在命令前显式传入生产连接串。
git pull
pnpm install --frozen-lockfile
cd apps/01mvp-web
DATABASE_URL="postgresql://user:pass@host:5432/prod?sslmode=require" \
pnpm db:status
DATABASE_URL="postgresql://user:pass@host:5432/prod?sslmode=require" \
pnpm db:deploy
DATABASE_URL="postgresql://user:pass@host:5432/prod?sslmode=require" \
pnpm db:status如果数据库提供 pooled URL 和 direct URL,迁移优先使用 direct URL;应用运行时再使用适合 Serverless 的 pooled URL。
适合已经有正式发布流程的项目。在 GitHub Actions 或其他 CI 里配置 DATABASE_URL secret,然后在部署前执行:
pnpm install --frozen-lockfile
cd apps/01mvp-web
pnpm db:status
pnpm db:deployCI 迁移失败时必须阻止生产部署继续执行。
适合 Docker、VPS、Zeabur 这类你能进入运行环境的部署方式。确认当前 shell 已注入生产 DATABASE_URL 后执行:
cd apps/01mvp-web
pnpm db:status
pnpm db:deploy
pnpm db:status执行前可以只输出连接串主机名,不要输出完整密码:
node -e 'const u=new URL(process.env.DATABASE_URL); console.log(u.host, u.pathname)'迁移注意事项
- 永远先迁移,后部署应用。新代码可能依赖新表结构
- 迁移文件只执行一次。Drizzle 会通过迁移记录表跟踪已应用迁移
- 大表迁移需要评估影响。ALTER TABLE 在大表上可能锁表,生产环境建议在低峰期执行
- 破坏性变更拆成两次发布。先加新字段或新表并兼容旧代码,部署稳定后再删除旧字段
- 回滚方案需要提前准备。重要迁移前先备份数据库或准备回滚 SQL
部署后验证
部署完成后,逐项验证以下功能:
基础访问
- 网站可通过生产域名正常访问
- HTTPS 证书有效
- 页面加载无超时或 500 错误
- 浏览器控制台无关键错误
用户认证
- 注册新账号流程正常
- 登录和登出正常
- OAuth 登录回调正常
- Session 刷新后仍然有效
数据库
- 数据读写正常
- 新注册用户数据写入成功
- Drizzle 数据库连接正常,无连接池错误
文件上传
- 图片或文件能上传到 S3
- 上传后可正常访问和展示
- 签名 URL 没有过期或权限错误
付费与通知
- 支付页面可正常加载
- Webhook 回调地址指向生产域名
- 注册、登录、通知类邮件能正常发送
常见部署问题
完整检查清单
构建
-
pnpm build通过 - Node.js 版本符合
22.x - Drizzle migration 已提交并执行
环境变量
-
DATABASE_URL指向生产数据库 -
BETTER_AUTH_SECRET已设置为强密钥 -
BETTER_AUTH_URL指向生产域名 -
NEXT_PUBLIC_SITE_URL指向生产域名 - AI、S3、支付、邮件等按需变量已配置
数据库
- migration 文件已提交到 Git
-
pnpm db:deploy已在生产数据库执行 -
pnpm db:status确认所有迁移已应用
域名和安全
- 自定义域名已绑定到部署平台
- DNS 记录已配置
- HTTPS 证书签发成功
- 边缘 WAF/DDoS 规则已配置
验证
- 部署后访问首页正常
- 登录注册流程正常
- 核心功能验证通过
- 支付、邮件、上传等按需功能验证通过