Nuxt 4 部署指南:Node、Nginx 与 PM2 的生产配置
Nuxt 4 默认可以构建成 Nitro Node 服务。它不是把 dist 目录交给 Nginx 就结束,而是由 Node 执行服务端渲染,再由 Nginx 负责域名、HTTPS、压缩和反向代理。
部署链路
浏览器 -> Nginx :443 -> Nuxt Nitro :3000 -> 后端 API
Nginx 是公网入口,Nuxt 只监听本机地址。这样既能保留 SSR,也避免直接暴露 Node 端口。
第一步:构建
pnpm install --frozen-lockfile
pnpm build
默认 Node server preset 的入口是:
.output/server/index.mjs
部署时至少需要完整上传 .output。不要只上传 .output/public,否则服务端路由和 SSR 都无法运行。构建机器与服务器架构差异较大时,最好在目标服务器或一致的 CI 容器中构建。
第二步:先直接启动验证
NODE_ENV=production \
HOST=127.0.0.1 \
PORT=3000 \
NUXT_PUBLIC_API_BASE=https://www.example.com/app-api \
NUXT_PUBLIC_SITE_URL=https://www.example.com \
node .output/server/index.mjs
Nuxt 的 Node 服务支持 PORT 或 NITRO_PORT,以及 HOST 或 NITRO_HOST。生产环境建议显式设置 NODE_ENV=production,避免开发警告进入日志。
验证本机服务:
curl -I http://127.0.0.1:3000/
curl http://127.0.0.1:3000/robots.txt
先确认 Node 服务正常,再配置 Nginx。这样出现 502 时容易判断是进程未启动,还是代理配置错误。
第三步:使用 PM2 守护
小内存服务器不要直接使用 instances: 'max',否则每个实例都会占用一份内存。博客流量不高时单实例更稳妥:
// ecosystem.config.cjs
module.exports = {
apps: [{
name: 'lemon-blog',
script: './.output/server/index.mjs',
instances: 1,
exec_mode: 'fork',
max_memory_restart: '350M',
env: {
NODE_ENV: 'production',
HOST: '127.0.0.1',
PORT: '3000',
NUXT_PUBLIC_API_BASE: 'https://www.example.com/app-api',
NUXT_PUBLIC_SITE_URL: 'https://www.example.com',
},
}],
}
pm2 start ecosystem.config.cjs
pm2 save
pm2 startup
pm2 startup 会输出一条需要执行的系统命令。完成后,服务器重启才会自动恢复进程。
第四步:Nginx 反向代理
server {
listen 443 ssl http2;
server_name www.example.com;
client_max_body_size 32m;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location /app-api/ {
proxy_pass http://127.0.0.1:48090/app-api/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
修改后先测试再重载:
nginx -t
nginx -s reload
如果使用宝塔,应在对应网站配置中修改,并保留面板生成的 SSL 证书路径。
发布更新的安全顺序
- 在新目录上传并解压构建产物。
- 检查环境变量和文件权限。
- 使用临时端口启动并访问首页。
- 切换软链接或替换当前版本目录。
- 执行
pm2 reload lemon-blog。 - 检查首页、文章详情、接口、robots 和 sitemap。
- 保留上一版产物,方便快速回滚。
502 与页面异常排查
| 现象 | 优先检查 |
|---|---|
| Nginx 502 | PM2 状态、3000 端口、Node 日志 |
| 页面无样式 | .output/public 是否完整、代理路径是否被重写 |
| API 地址仍是本地 | 运行时变量名、PM2 重启、public 配置声明 |
| 刷新动态路由 404 | 请求是否真的进入 Nuxt,而不是静态目录 |
| 内存持续增长 | PM2 内存、日志量、缓存与接口响应大小 |
常用诊断命令:
pm2 status
pm2 logs lemon-blog --lines 100
ss -lntp | grep 3000
curl -I http://127.0.0.1:3000/articles/example
小结
可靠部署的关键是把每一层分开验证:先构建产物,再验证 Node,随后接入 PM2,最后配置 Nginx。遇到问题时沿着浏览器、Nginx、Nuxt、API 的链路逐层检查,比反复重装依赖更有效。