无服务器部署与 CI CD 自动化
11.10 部署踩坑与解决
Tip
部署通过了只是开始。真正的恐怖故事,往往发生在用户点击那一刻。
1. 为什么要学这个?
典型场景: Vercel 撒花了,域名生成了。 你兴奋地发给朋友。 朋友点开一看:500 Internal Server Error。 这时候你 panic 了。 本地明明是好的啊! 本章汇总了 Next.js + Vercel 部署最常见的"鬼打墙"问题,教你如何像老司机一样看日志修车。
2. 核心问题清单
问题一:Env Var 丢失 (最常见)
- 现象:数据库连不上,API 报错 Unauthenticated。
- 原因:你本地有
.env,但你忘了去 Vercel Dashboard 填环境变量。 - 解法:去 Settings -> Environment Variables 再填一遍。
- 注意:
NEXT_PUBLIC_开头的变量会暴露给浏览器,私钥千万别带这前缀。
问题二:Hardcoded Localhost (硬编码)
- 现象:网页打不开,控制台报错
Mixed Content或Connection Refused。 - 原因:代码里写死了
fetch('http://localhost:3000/api/user')。 - 解法:永远使用相对路径
fetch('/api/user'),或者使用环境变量process.env.NEXT_PUBLIC_API_URL。
问题三:Database IP Whitelist (白名单)
- 现象:
PrismaClientInitializationError: Can't reach database server。 - 原因:你的云数据库(如阿里云 RDS)设置了白名单只允许你的家庭 IP 访问。
- 解法:Vercel 的出口 IP 是动态的,你必须把数据库白名单设为
0.0.0.0/0(允许全网访问)。前提是你的数据库密码足够复杂!
问题四:Cold Start (冷启动)
- 现象:第一次访问要转圈 2 秒,刷新一下就快了。
- 原因:Serverless 函数"睡着了"。
- 解法:这是 Serverless 的特性(省钱的代价)。如果无法接受,请升级 Pro 版或使用 Edge Runtime。
3. 排查流程图 (SOP)
graph TD
Start["访问报错 (500/404)"] --> CheckLog["Step 1: 看 Vercel Logs (Runtime Logs)"]
CheckLog --"Connection Timeout"--> DB{"Step 2: 数据库白名单"}
DB --"已限制"--> FixIP["由 127.0.0.1 改为 0.0.0.0/0"]
CheckLog --"Env undefined"--> Env{"Step 3: 环境变量"}
Env --"漏填"--> FixEnv["去 Dashboard 补全"]
CheckLog --"Network Error"--> Code{"Step 4: 硬编码 Localhost?"}
Code --"Yes"--> FixPath["改为相对路径 /api/..."]
style FixIP fill:#c8e6c9,stroke:#2e7d32
style FixEnv fill:#c8e6c9,stroke:#2e7d32
style FixPath fill:#c8e6c9,stroke:#2e7d32
4. 真实案例
Story
"消失的头像"
某网站允许用户上传头像,后端把文件存到了 public/uploads 目录。
上传完立刻能看到。
但过了一会儿(或者重新部署后),头像全变成了 404。
原因:开发者忘了 Serverless 是无状态的。
Vercel 的文件系统是只读的(除了 /tmp,而且 /tmp 也会被不定时清空)。你写入的文件,就像写在沙滩上,潮水(重置)一来就没了。
Vibe 心法: 不要试图抗拒云的特性。 文件存 OSS (S3),状态存 Redis/DB。 任何依赖"本地文件系统"的逻辑,在 Serverless 世界里都是必死无疑的坑。
5. 本章小结
- Logs:报错先看 Vercel Function Logs,不要瞎猜。
- Stateless:永远不要在本地存文件。
- Whitelist:如果数据库连不上,99% 是白名单问题。