部署准备
为生产准备应用:构建优化、环境变量、健康检查和回滚。
为什么
首次部署是'开发能用'遇'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:命令、预期时长、回滚命令和值班联系。