部署指南

上线前检查、部署方式选择、环境变量、数据库迁移和部署后验证。

项目是 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 部署

部署前检查清单

在触发任何部署之前,逐项确认以下内容:

  • 本地 pnpm build 构建成功,无 TypeScript 错误
  • pnpm db:status 确认所有 migration 已提交到 Git
  • .env.prd 或生产变量源中的必填变量已同步到 Zeabur
  • BETTER_AUTH_URLNEXT_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_URLPostgreSQL 连接串postgresql://user:pass@host:5432/prod
BETTER_AUTH_SECRETAuth 签名密钥随机生成的强密钥
BETTER_AUTH_URLAuth 回调基础 URLhttps://your-domain.com
NEXT_PUBLIC_SITE_URL站点公开 URLhttps://your-domain.com
OPENAI_API_KEYAI API 密钥sk-...

按需变量

类型变量
S3 存储S3_ENDPOINTS3_REGIONS3_ACCESS_KEY_IDS3_SECRET_ACCESS_KEYS3_BUCKETNEXT_PUBLIC_S3_ENDPOINT
OAuth 登录GOOGLE_CLIENT_IDGOOGLE_CLIENT_SECRETGITHUB_CLIENT_IDGITHUB_CLIENT_SECRETWECHAT_WEBSITE_APP_IDWECHAT_WEBSITE_APP_SECRET
支付STRIPE_SECRET_KEYSTRIPE_WEBHOOK_SECRETNEXT_PUBLIC_STRIPE_PRICE_PRO_MONTHLYNEXT_PUBLIC_STRIPE_PRICE_PRO_YEARLYWAFFO_MERCHANT_IDWAFFO_PRIVATE_KEY
邮件RESEND_API_KEYZEABUR_EMAIL_API_KEYEMAIL_FROMCONTACT_EMAIL
统计与安全NEXT_PUBLIC_UMAMI_WEBSITE_IDNEXT_PUBLIC_UMAMI_SCRIPT_URLNEXT_PUBLIC_GOOGLE_ANALYTICS_IDEDGE_WAF_PROVIDEREDGE_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:deploy

db: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:deploy

CI 迁移失败时必须阻止生产部署继续执行。

适合 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 规则已配置

验证

  • 部署后访问首页正常
  • 登录注册流程正常
  • 核心功能验证通过
  • 支付、邮件、上传等按需功能验证通过