---
title: "宝塔面板 Node.js PM2 部署教程"
description: "在宝塔面板（BT Panel）中使用 PM2 部署、守护与监控 Node.js 项目的完整教程，覆盖源码上传、npm 依赖安装、PM2 启动脚本配置、开机自启与 Nginx 反向代理对外发布的全链路操作。"
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.bt.cn/llms.txt
> Use this file to discover all available pages before exploring further.

# 宝塔面板 Node.js PM2 部署教程

## Node.js PM2 部署

## 下载源码

使用 Git 克隆项目源码到本地：

```bash
git clone https://gitee.com/chancms/ChanCMS.git
```

![下载源码](/img/practical-tutorials/pm2-deployment/pm2-000.png)

## 创建并配置数据库

在宝塔面板中创建项目所需的数据库。

![创建数据库](/img/practical-tutorials/pm2-deployment/pm2-001.png)

## 添加 PM2 项目

### 方案 1：使用启动文件启动

直接使用项目的 `app.js` 启动文件进行部署。

![使用 app.js 启动](/img/practical-tutorials/pm2-deployment/pm2-002.png)

### 方案 2：使用 ecosystem.config.cjs 配置文件（推荐）

推荐使用现代化的 PM2 配置文件方式，便于管理和维护。

#### 手动创建并写入配置文件

##### 配置项说明

主要配置项及其作用：

- **name**：项目名称，建议与网站名称保持一致
- **script**：启动文件，一般是 `server.js` 或 `app.js`，是项目的入口文件
- **cwd**：项目运行目录，使用绝对路径兼容性更好
- **env**：项目的环境变量，统一管理所有环境变量，方便维护
- **instances / exec_mode**：处理性能优化相关配置

![配置项说明](/img/practical-tutorials/pm2-deployment/pm2-003.png)

##### 完整配置文件

创建 `ecosystem.config.cjs` 文件，配置内容如下：

```javascript
module.exports = {
  apps: [
    {
      // ===================== 基础标识配置 =====================
      
      /**
       * 进程名称：自定义名称，用于 PM2 命令管理（如 pm2 start/stop/restart ChanCMS）
       * 建议与项目名称一致，便于多应用区分
       */
      name: "ChanCMS",

      /**
       * 应用入口文件：ChanCMS 项目根目录的启动文件（文档明确为 app.js）
       * 路径说明：相对路径基于执行 pm2 命令的目录（建议在项目根目录执行）
       */
      script: "./app.js",

      /**
       * 运行目录（cwd）：指定 PM2 启动应用时的工作目录
       * 作用：确保所有相对路径（如 ./logs、./data、./app.js）都基于项目根目录解析，避免路径错误
       * 配置说明：替换为你的 ChanCMS 项目实际部署路径（必须是绝对路径）
       */
      cwd: "/www/wwwroot/ChanCMS",

      // ===================== 性能优化配置 =====================
      
      /**
       * 执行模式：Cluster 模式（多核 CPU 推荐）
       * 原理：通过多进程共享端口，充分利用 CPU 核心，提升并发处理能力
       * 替代值："fork"（单进程模式，适合开发环境或单核服务器）
       */
      exec_mode: "cluster",

      /**
       * 实例数：自动适配 CPU 核心数（生产环境最优选择）
       * 自定义配置：若需限制实例数，可改为具体数字（如 2 表示启动 2 个进程）
       * 注意：Cluster 模式下实例数建议 ≤ CPU 核心数，避免进程切换开销
       */
      instances: "max",

      // ===================== 环境变量配置 =====================
      
      /**
       * 基础环境变量：所有环境共享的配置（开发环境默认值）
       */
      env: {
        // 默认环境（开发环境）
        APP_DEBUG: true,        // 开发环境启用调试模式
        PORT: 3000,             // 开发环境端口
        LOG_LEVEL: "debug",     // 开发环境显示详细日志
        NODE_ENV: "production",
      },

      /**
       * 生产环境变量：--env production 启动时加载（覆盖基础环境变量）
       * 整合所有提供的 ChanCMS 配置，直接对接项目需求
       */
      env_production: {
        // 基础环境标识
        NODE_ENV: "production",          // 项目指定生产环境标识（与配置文件一致）
        APP_DEBUG: false,                // 生产环境关闭调试模式（避免泄露敏感信息）

        // JWT 认证配置
        JWT_SECRET: "ChanCMS",           // JWT 加密密钥（项目默认值，建议生产环境修改为随机字符串）
        JWT_EXPIRES_IN: "1d",            // JWT 有效期（1天，支持 s/m/h/d 单位）
        JWT_REFRESH: false,              // 关闭 JWT 刷新功能（按项目配置）

        // 加盐配置（密码/用户信息加密）
        PASSWORD_SALT: 12,               // 密码加密加盐系数
        USER_SALT: 12,                   // 用户信息加密加盐系数
        AES_SALT: "chancms-aes-prd",     // AES 加密密钥（生产环境专用）

        // WAF 防护配置
        WAF_LEVEL: 1,                    // WAF 防护等级（1=基础防护，按项目支持的等级调整）

        // 数据库核心配置（与提供的 DB 信息完全一致）
        DB_HOST: "localhost",            // 数据库地址（本地部署）
        DB_USER: "chan_cms",             // 数据库用户名
        DB_PASS: "wAFaihDwxZS5Zxbh",     // 数据库密码
        DB_PORT: 3306,                   // 数据库端口（MySQL 默认 3306）
        DB_DATABASE: "chan_cms",         // 数据库名称
        DB_DEBUG: false,                 // 生产环境关闭数据库调试日志
        DB_POOL_MIN: 0,                  // 数据库连接池最小连接数
        DB_POOL_MAX: 2,                  // 数据库连接池最大连接数（按服务器性能调整）
        DB_CLIENT: "mysql2",             // 数据库客户端（项目指定 mysql2）
        DB_FILENAME: "./data/chancms.sqlite", // SQLite 备用数据库路径（项目兼容配置）

        // 站点服务配置
        PORT: 3000,                      // 项目指定服务端口（如需通过 Nginx 反向代理，保持此端口即可）
        BODY_LIMIT: "300kb",             // 请求体大小限制（防止大文件上传攻击）
        CORS_ORIGIN: "*",                // 跨域允许所有来源（生产环境建议指定具体域名，如 "https://your-domain.com"）

        // 日志配置
        LOGGER_LEVEL: "tiny",            // 生产环境日志级别（精简日志，减少磁盘占用）

        // 邮箱服务配置（用于验证码、通知发送）
        EMAIL_HOST: "smtp.qq.com",       // QQ 邮箱 SMTP 服务器
        EMAIL_PORT: 587,                 // SMTP 端口（587=非加密，465=SSL加密）
        EMAIL_USER: "you-email@qq.com",  // 发件人邮箱账号
        EMAIL_PASS: "you-email-pass",    // 邮箱授权码（非登录密码，需在邮箱后台开启 SMTP 并获取）
        EMAIL_FROM: "you-email@qq.com",  // 发件人显示邮箱（与 EMAIL_USER 一致）
        EMAIL_SECURE: true,              // 启用 SSL 加密（QQ 邮箱 SMTP 需开启）
        EMAIL_CODE: "1234",              // 邮箱验证码默认值（项目内部使用，可忽略）
        EMAIL_TO: "123123123@qq.com",    // 默认收件人邮箱（用于系统通知）

        // 微信公众号配置（公众号内登录功能）
        WECHAT_APPID: "wx-you-appid",    // 公众号 AppID（需替换为实际申请的 AppID）
        WECHAT_APPSECRET: "wx-you-xxx",  // 公众号 AppSecret（替换为实际密钥）
        WECHAT_REDIRECT_URI: "https://vip.chancms.top", // 公众号登录回调地址（需在公众号后台配置）
        WECHAT_TOKEN: "123",             // 公众号消息校验 Token（替换为自定义随机字符串）

        // 微信开放平台配置（PC 端扫码登录）
        WECHAT_OPEN_APPID: "wx-you-appid",         // 开放平台 AppID（替换为实际 AppID）
        WECHAT_OPEN_APPSECRET: "wx-you-appsecret", // 开放平台 AppSecret（替换为实际密钥）

        // 微信小程序配置（小程序登录/对接）
        MINIPROGRAM_APPID: "your-miniprogram-appid",         // 小程序 AppID（替换为实际 AppID）
        MINIPROGRAM_APPSECRET: "your-miniprogram-appsecret", // 小程序 AppSecret（替换为实际密钥）
      },

      // ===================== 日志配置 =====================
      
      /**
       * 错误日志路径：记录应用崩溃、异常等错误信息
       * 路径说明：项目根目录下的 logs 文件夹，自动创建（需确保目录权限可写）
       */
      error_file: "./logs/chancms-error.log",

      /**
       * 输出日志路径：记录应用正常运行日志（如接口请求、业务日志）
       */
      out_file: "./logs/chancms-out.log",

      /**
       * 日志合并：多实例（Cluster 模式）日志合并到同一个文件
       * 优势：避免日志分散，便于按时间线排查问题
       */
      merge_logs: true,

      /**
       * 日志时间格式：统一日志时间戳格式，便于日志分析工具解析
       * 格式说明：YYYY-MM-DD HH:mm:ss（年-月-日 时:分:秒）
       */
      log_date_format: "YYYY-MM-DD HH:mm:ss",

      /**
       * 日志轮转配置：避免单个日志文件过大（PM2 v6+ 支持）
       * 作用：自动分割日志，保留历史日志，防止磁盘占满
       */
      log_rotate: {
        size: "10M",        // 单个日志文件最大 size（超过则分割）
        max: 30,            // 保留最近 30 个日志文件
        compress: true,     // 压缩历史日志（gzip 格式，节省磁盘空间）
        interval: "1d",     // 日志轮转间隔（1d = 每天轮转一次）
      },

      // ===================== 稳定性配置 =====================
      
      /**
       * 自动重启：进程异常退出时自动重启（生产环境必需）
       * 场景：应对内存泄漏、代码异常等导致的进程崩溃，保障服务可用性
       * 例外：通过 process.exit(0) 正常退出时，不会触发重启
       */
      autorestart: true,

      /**
       * 重启延迟：异常退出后，延迟 5 秒重启（避免频繁重启）
       */
      restart_delay: 5000,

      /**
       * 监听文件变化：生产环境禁用（避免代码更新误触发重启）
       */
      watch: false,

      /**
       * 内存限制：进程占用内存超过阈值时自动重启（防止 OOM 崩溃）
       * 配置依据：ChanCMS 轻量特性，1G 足够生产环境使用（可根据服务器内存调整）
       */
      max_memory_restart: "1G",

      // ===================== 高级配置 =====================
      
      /**
       * 启动超时时间：超过 30 秒未启动成功则视为启动失败
       * 适配场景：ChanCMS 启动需加载数据库、插件等，预留充足启动时间
       */
      timeout: 30000,

      /**
       * 健康检查：定期检测应用端口是否可用（保障服务存活）
       * 原理：PM2 会访问指定端口，无响应则触发重启
       */
      health_check: {
        enable: true,
        interval: 60,  // 每 60 秒检查一次
        timeout: 5,    // 检查超时时间 5 秒
        port: 3000,    // 与生产环境 PORT 一致
      },

      /**
       * 环境变量加载：自动加载项目根目录的 .env 文件（PM2 v5+ 支持）
       * 优势：无需手动 require dotenv，与 ChanCMS 配置加载逻辑兼容
       */
      merge_env_vars: true,

      /**
       * 进程优先级：设置为 19（最低优先级），避免抢占核心服务资源
       */
      nice: 19,
    },
  ]
};
```

![配置文件示例 1](/img/practical-tutorials/pm2-deployment/pm2-004.png)

![配置文件示例 2](/img/practical-tutorials/pm2-deployment/pm2-005.png)

![配置文件示例 3](/img/practical-tutorials/pm2-deployment/pm2-006.png)

#### 添加项目并启动

在宝塔面板中添加 PM2 项目并启动。

![添加项目](/img/practical-tutorials/pm2-deployment/pm2-007.png)

## 配置域名和反向代理

配置域名和 Nginx 反向代理，以便通过域名访问应用。

:::info 说明
以下截图展示的是内网配置的 host，仅用于测试环境。
:::

![域名配置](/img/practical-tutorials/pm2-deployment/pm2-008.png)

![反向代理设置](/img/practical-tutorials/pm2-deployment/pm2-009.png)

![反向代理配置](/img/practical-tutorials/pm2-deployment/pm2-010.png)

![Nginx 配置](/img/practical-tutorials/pm2-deployment/pm2-011.png)

![站点管理](/img/practical-tutorials/pm2-deployment/pm2-012.png)

![PM2 管理界面](/img/practical-tutorials/pm2-deployment/pm2-013.png)

![应用运行状态](/img/practical-tutorials/pm2-deployment/pm2-014.png)

![访问测试](/img/practical-tutorials/pm2-deployment/pm2-015.png)

Source: https://docs.bt.cn/practical-tutorials/nodejs-pm2-deployment/index.mdx
