一句话:Nuxt 3 生产跑的是 .output/server/index.mjs,PM2 守护进程,Nginx 反代 5050。

写在前面

Nuxt 3 npm run build 后不是静态 dist,而是 Nitro 服务端 bundle。Linux 上常用 PM2 做进程守护、日志与开机自启。

本文对齐本仓库 blog-home-nuxt/ecosystem.config.js 与生产 Nginx 分流策略(详见自文档「三端架构与请求链路」)。


部署步骤

1. 本地/CI 构建

cd blog-home-nuxt
npm ci
npm run build

产物目录:.output/(含 server/index.mjspublic/)。

2. 上传到服务器

.output 整个目录放到例如 /blog/blog-home-nuxt/.output,同目录放置 ecosystem.config.jspackage.json(如需)。

3. PM2 配置

// blog-home-nuxt/ecosystem.config.js
module.exports = {
  apps: [{
    name: 'BlogHomeNuxt',
    script: '.output/server/index.mjs',
    exec_mode: 'fork',        // Nuxt SSR 建议 fork;cluster 曾出现访问异常
    instances: 1,
    watch: false,             // 生产关闭 watch
    autorestart: true,
    max_memory_restart: '500M',
    env_production: {
      NODE_ENV: 'production',
      PORT: '5050',
      NITRO_PORT: '5050',
      HOST: '0.0.0.0',
    },
  }],
};

启动:

pm2 start ecosystem.config.js --env production
pm2 save
pm2 startup   # 按提示执行生成的命令,开机自启

4. Nginx 反代

生产环境 HTML 走 SSR,静态 hash 资源可直出(见 deploy/nginx/conf.d/jiang-xia.top.conf):

location / {
    try_files $uri @nuxt;
}
location @nuxt {
    proxy_pass http://127.0.0.1:5050;
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
}

API 仍反代到 Nest 5000,与 Nuxt 进程分离。


常用 PM2 命令

命令 说明
pm2 list 进程列表
pm2 logs BlogHomeNuxt 查看日志
pm2 restart BlogHomeNuxt 重启
pm2 reload ecosystem.config.js --env production 零停机 reload(cluster 时更有用)
pm2 update launching 时可尝试

踩坑与注意

  1. 构建 OOM:Nuxt 3 build 吃内存,小机器加 swap 或 CI 构建后只上传 .output
  2. Windows cluster 失败:开发机用 fork;生产 Linux 也建议 Nuxt 单实例 + Nginx 负载多机
  3. Nest + express-session:多实例 session 不同步,需 Redis store 或 sticky session——不要无脑 PM2 cluster Nest
  4. 路径错误:旧版写 output/server/index.mjs,Nuxt 3 正确为 .output/server/index.mjs
  5. 环境变量:生产 NUXT_* / runtimeConfig 在 build 时 baked 部分变量,改 env 后可能需重新 build

小结

  • 流程:build → 上传 .outputpm2 start → Nginx @nuxt 反代 5050
  • 配置见仓库根 blog-home-nuxt/ecosystem.config.js
  • 与 Nest API(5000)分开进程,由 Nginx 按路径分流

延伸阅读