Z
ZeniCore
/文档中心
文档构建部署

构建部署

2026-04-21 v1.0.0

构建部署

环境要求

  • Node.js >= 18.0.0
  • npm >= 9.0.0 或 pnpm >= 8.0.0
  • PM2(用于生产环境进程管理)
  • Nginx(用于反向代理)

构建步骤

# 1. 安装依赖
npm install

# 2. 类型检查
npm run typecheck

# 3. 构建生产版本
npm run build

# 4. 预览生产版本
npm run preview

构建产物详解

执行 npm run build 后,会生成 .output/ 目录:

.output/
├── public/                    # 静态资源目录(必须上传)
│   ├── _nuxt/                 # Nuxt 编译后的 JS/CSS 资源
│   │   ├── entry.*.js         # 入口文件
│   │   ├── entry.*.css        # 入口样式
│   │   └── *.js               # 其他模块文件
│   ├── images/                # 图片资源
│   ├── favicon.ico            # 网站图标
│   └── *.html                 # 预渲染的静态页面
│
├── server/                    # SSR 服务器目录(必须上传)
│   ├── index.mjs              # 服务入口文件(主程序)
│   ├── package.json           # 服务依赖信息
│   ├── chunks/                # 代码分块
│   │   ├── app.mjs            # 应用代码
│   │   ├── runtime.mjs        # 运行时代码
│   │   └── *.mjs              # 其他模块
│   └── node_modules/          # 服务端依赖
│
└── nitro.json                 # Nitro 配置信息

需要上传的文件

方式一:完整部署(推荐)

需要上传的目录:
├── .output/public/            # 静态资源(约 5-20 MB)
├── .output/server/            # SSR 服务器(约 10-50 MB)
└── ecosystem.config.js        # PM2 配置文件(可选)

方式二:仅 SSR 服务

如果使用 Nginx 托管静态资源,只需上传:

需要上传的目录:
├── .output/server/            # SSR 服务器
└── ecosystem.config.js        # PM2 配置文件

方式三:静态站点部署(SSG)

如果项目配置为纯静态生成(无 SSR),只需上传:

需要上传的目录:
└── .output/public/            # 静态文件

上传构建产物到服务器

方法一:SCP 上传(推荐)

# 压缩构建产物
tar -czvf output.tar.gz .output

# 上传到服务器
scp output.tar.gz user@your-server-ip:/home/user/zenicore-nuxt/

# 登录服务器解压
ssh user@your-server-ip
cd /home/user/zenicore-nuxt/
tar -xzvf output.tar.gz

方法二:rsync 同步(增量更新推荐)

# 同步整个 .output 目录
rsync -avz --delete .output/ user@your-server-ip:/opt/zenicore-nuxt/.output/

方法三:FTP/SFTP 工具

使用 FileZilla、WinSCP 等工具上传 .output 文件夹

服务器目录结构建议

/opt/zenicore-nuxt/            # 应用根目录
├── .output/                   # 构建产物
│   ├── public/                # 静态资源
│   └── server/                # SSR 服务
├── logs/                      # 日志目录
│   ├── access.log             # 访问日志
│   └── error.log              # 错误日志
├── ecosystem.config.js        # PM2 配置
└── .env.production            # 生产环境变量

完整部署流程

# ===== 本地操作 =====
# 1. 拉取最新代码
git pull origin main

# 2. 安装依赖
npm install

# 3. 类型检查
npm run typecheck

# 4. 构建
npm run build

# 5. 压缩
tar -czvf output.tar.gz .output ecosystem.config.js

# 6. 上传
scp output.tar.gz user@your-server-ip:/tmp/

# ===== 服务器操作 =====
# 7. 登录服务器
ssh user@your-server-ip

# 8. 创建目录(首次)
mkdir -p /opt/zenicore-nuxt/logs

# 9. 解压
cd /opt/zenicore-nuxt
tar -xzvf /tmp/output.tar.gz

# 10. 配置环境变量(首次)
cat > .env.production << EOF
NUXT_PUBLIC_API_BASE=https://api.example.com/api
NODE_ENV=production
PORT=3000
EOF

# 11. 启动服务
pm2 restart zenicore-nuxt || pm2 start ecosystem.config.js

# 12. 验证
curl http://localhost:3000

PM2 部署

安装 PM2

npm install -g pm2

启动应用

方式一:直接启动

# 启动服务
pm2 start .output/server/index.mjs --name zenicore-nuxt

# 查看状态
pm2 status

# 查看日志
pm2 logs zenicore-nuxt

# 重启应用
pm2 restart zenicore-nuxt

# 开机自启
pm2 save
pm2 startup

方式二:使用 npm start 启动(推荐)

项目已配置自动添加启动脚本,构建后可直接使用:

# 本地构建时会自动配置
npm run build

# 服务器上启动
cd .output/server
npm start

# 或使用 PM2 管理
pm2 start npm --name zenicore-nuxt -- start

方式三:自动配置脚本

项目根目录的 scripts/setup-server.js 会在构建后自动配置:

// scripts/setup-server.js
const fs = require('fs')
const path = require('path')

const serverPkgPath = path.join(__dirname, '../.output/server/package.json')

if (fs.existsSync(serverPkgPath)) {
  const pkg = JSON.parse(fs.readFileSync(serverPkgPath, 'utf8'))
  pkg.scripts = {
    start: 'node index.mjs',
    dev: 'node --watch index.mjs'
  }
  fs.writeFileSync(serverPkgPath, JSON.stringify(pkg, null, 2))
  console.log('✅ 已配置服务器启动脚本')
}

package.json 中的构建命令:

{
  "scripts": {
    "build": "nuxt build && node scripts/setup-server.js",
    "start": "node .output/server/index.mjs"
  }
}

PM2 配置文件

创建 ecosystem.config.js

module.exports = {
  apps: [{
    name: 'zenicore-nuxt',
    script: './.output/server/index.mjs',
    cwd: '/opt/zenicore-nuxt',
    instances: 'max',
    exec_mode: 'cluster',
    env: {
      NODE_ENV: 'production',
      PORT: 3000
    },
    error_file: './logs/error.log',
    out_file: './logs/out.log',
    max_memory_restart: '1G'
  }]
}

Nginx 配置

upstream zenicore_app {
    server 127.0.0.1:3000;
    keepalive 64;
}

server {
    listen 80;
    server_name example.com;

    # 静态资源目录
    root /opt/zenicore-nuxt/.output/public;

    # 静态资源缓存
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }

    # SSR 代理
    location / {
        proxy_pass http://zenicore_app;
        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;
    }
}

增量更新流程

# 本地操作
npm run build
rsync -avz --delete .output/ user@your-server-ip:/opt/zenicore-nuxt/.output/

# 服务器操作
ssh user@your-server-ip
pm2 restart zenicore-nuxt