Skip to content
返回构建教程

部署准备

为生产准备应用:构建优化、环境变量、健康检查和回滚。

为什么

首次部署是'开发能用'遇'prod 能用'——差距总比预期大。生产需优化构建(压缩、代码分割、tree-shake)、正确环境变量(无开发默认泄漏)、负载均衡器健康检查、部署坏时回滚策略。没有这些,首次部署是 4 小时调试:bundle 5MB、应用连开发 DB、LB 因无健康端点标不健康、崩时无路回。准备把首次部署从危机变 5 分钟例行。

何时使用

应用 v1 功能完成时。约 2-3 小时。永不跳过——每应用终部署。

如何做

1. 跑生产构建并检查输出
   - next build → 查 .next/static bundle 大小;目标初始 JS < 200KB
   - 用 @next/bundle-analyzer 找重导入;路由代码分割

2. 平台设所有环境变量(Vercel、Cloudflare、Fly)
   - DATABASE_URL、NEXTAUTH_SECRET 等——永不提交 .env 到 prod
   - prod 用不同 DATABASE_URL(非开发 DB)

3. 加 /api/health 端点检查 DB + 关键服务
   - 健康返回 200,任依赖宕返回 503
   - 负载均衡器用此从坏实例排水

4. 设回滚机制:保留前部署,失败时换
   - Vercel:即时回滚到前部署
   - Docker:保留前镜像 tag,健康检查失败时重部署

5. 先 staging 部署并对其跑 e2e 套件
   - 永不无 staging 验证部署 prod
   - staging 和 prod 用同构建产物(构建一次,部署两次)

示例

// /api/health——检查 DB + 缓存
export async function GET() {
  const checks = await Promise.allSettled([
    prisma.$queryRaw`SELECT 1`,           // DB
    fetch(env.REDIS_URL + "/ping"),         // 缓存
  ]);
  const healthy = checks.every((c) => c.status === "fulfilled");
  return new Response(healthy ? "ok" : "降级", { status: healthy ? 200 : 503 });
}

// next.config.js——CI bundle 分析
const withBundleAnalyzer = require("@next/bundle-analyzer")({ enabled: process.env.ANALYZE === "true" });
module.exports = withBundleAnalyzer({ experimental: { optimizePackageImports: ["lucide-react"] } });

// 部署脚本(构建一次,先 staging 再 prod)
// npm run build && vercel deploy --prebuilt --target staging && vercel promote staging

常见问题

  • ⚠部署开发 DB URL 到 prod,应用在生产读写开发数据。
  • ⚠无健康检查,LB 持续发流量到崩实例直到人注意。
  • ⚠无回滚,坏部署留数小时直到有人想出如何回退。
  • ⚠无路由代码分割致 5MB 初始 bundle,落地页 8 秒加载。

最佳实践

  • ✓构建一次同产物部署 staging 和 prod——消除构建差异致'staging 能用 prod 坏'。
  • ✓健康检查失败自动回滚(Vercel、Cloudflare)——坏部署 60 秒回退非 60 分钟。
  • ✓CI 对构建站跑 Lighthouse,性能分降 80 下则失败。
  • ✓保留部署 runbook:命令、预期时长、回滚命令和值班联系。