前言
有没有过这样的体验:你写完 Next.js 项目,心潮澎湃,结果部署时却被"神秘的服务器玄学"劝退。
- 代码跑本地毫无问题 🚀
- 上服务器一跑,进程一挂,访问404 😱
于是,老司机们发明了"三板斧":
Docker 装环境,PM2 护进程,Nginx 当大门 。
这三件宝齐活了,你的Next.js应用不仅能启动,还能天天在线,连服务器重启都打不倒它。
下面,我们一起来走一遍从底层原理到实操的旅途吧。
一、三兄弟的江湖定位
1. Docker 🐳
- 底层原理 :其实就是 Linux 的 Namespace + Cgroup,把进程关进独立小黑屋,既隔离又限流。
- 用处:在别人电脑和你服务器上给 Next.js 提供一个一模一样的小环境,不会因为"我装的是Node 18,你服务器是Node 14"吵架。
2. PM2 👷
- 底层原理:就是"进程管理器"。底层靠 fork/spawn 系统调用不断盯着你的 Node.js 程序,如果程序猝死,它马上拉起来。
- 用处 :保证 Next.js 服务 不挂 、可平滑重启 、日志集中管理。
3. Nginx 🦊
- 底层原理:内核用 epoll 做多路复用,能顶住成千上万请求而不慌。
- 用处:做反向代理,让小透明的 Next.js 后端藏在大门后面,同时负责负载均衡、SSL证书、静态缓存。
二、部署的宏观蓝图
📜 流程像这样:
- 写 Dockerfile → 打包 Next.js 应用
- Docker 运行容器 → 保证环境一致
- 容器内部用 PM2 → 保证进程活着
- 宿主机 Nginx → 把流量转发到容器
可以脑补一个舞会场景:
- Docker 是舞池,帮你提供隔音场地;
- Next.js 应用是演员;
- PM2 是安保,防止演员突然跑掉;
- Nginx 是门口的保安,负责把观众引入正确的舞台。
三、动手实操 🎬
1. 写 Dockerfile
bash
# 基于官方Node镜像
FROM node:18-alpine
# 工作目录
WORKDIR /app
# 拷贝依赖
COPY package*.json ./
# 安装依赖
RUN npm install
# 拷贝源代码
COPY . .
# 构建Next.js生产版本
RUN npm run build
# 安装PM2
RUN npm install pm2 -g
# 暴露端口
EXPOSE 3000
# 用PM2启动
CMD ["pm2-runtime", "start", "npm", "--", "start"]
2. 构建镜像 & 运行容器
perl
# 构建镜像
docker build -t my-next-app .
# 运行容器
docker run -d --name next-app -p 3000:3000 my-next-app
背后发生了什么?
- 文件被打包进层(layer),类似洋葱皮;
- 容器启动后,本质上就是一个在黑屋子里孤零零跑的 Node 进程。
3. 用 Nginx 做反向代理
新建配置文件(/etc/nginx/conf.d/next.conf
):
ini
server {
listen 80;
server_name your-domain.com;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
4. 重启 Nginx
bash
nginx -t # 检查配置是否正确
systemctl reload nginx
🎉 访问 http://your-domain.com
就能看到你的 Next.js 网站啦!
四、底层逻辑可视化
来一张 ASCII 风格小图:
scss
用户浏览器请求
|
[Nginx]
|
┌────────┴─────────┐
| |
(PM2保护) (容器隔离)
Next.js App <--- Docker
这小图虽然简单,但足够展示:
- Nginx 负责进出口
- Docker 保证环境
- PM2 就像保镖,保证演员不倒
五、踩坑提醒 ⚠️
- Node版本:Next.js 经常挑剔 Node 版本,Docker 镜像一定要选对。
- 内存限制:Cgroup 限内存,如果PM2一旦报 OOM(内存溢出),说明小黑屋太小。
- Nginx缓存:别忘了清配置或重新加载,否则你以为是代码问题,其实只是"缓存鬼打墙"。
六、幽默总结
部署 Next.js 就像养猫:
- 猫=应用,天天乱跑;
- Docker=猫笼,把猫关进去;
- PM2=自动喂食机,防止猫饿死;
- Nginx=大门口的门卫,决定谁能摸猫。
有了 Docker + PM2 + Nginx,你的猫就能活得又长又自在,连凌晨3点服务器重启都不怕。