pm2 笔记
约 1729 字大约 6 分钟
2026-02-10
推荐方式:ecosystem 配置文件(而不是 pm2 start app.js 一把梭)
好处:可版本管理、参数可追溯、支持多环境、支持集群、统一日志、可一键 reload。
安装
npm i -g pm2pm2 -v如果服务器有多个 node 版本(nvm),确保你在正确的 node 环境里装的 pm2:
which node
which pm2
node -v
pm2 -v在项目中需要明确 启动命令是哪一个,不太推荐在 pm2 里包一层 npm(npm run start),但也可用,建议优先用 node 直接跑入口文件,更稳定、少一层壳。
配置文件
在项目根目录创建:
pm2 ecosystem会生成 ecosystem.config.js,然后改成下面这种“生产级模板”。
通用模板
pm2 ecosystem 生成的是“通用模板”,会把 apps(进程定义)+ deploy(可选的 PM2 部署系统)一起塞进来。
module.exports = {
apps : [{
script: 'index.js',
watch: '.'
}, {
script: './service-worker/',
watch: ['./service-worker']
}],
deploy : {
production : {
user : 'SSH_USERNAME',
host : 'SSH_HOSTMACHINE',
ref : 'origin/master',
repo : 'GIT_REPOSITORY',
path : 'DESTINATION_PATH',
'pre-deploy-local': '',
'post-deploy' : 'npm install && pm2 reload ecosystem.config.js --env production',
'pre-setup': ''
}
}
};module.exports = { ... } Node 的 CommonJS 导出语法,PM2 读取这个对象作为配置。
apps: [...] 是“进程定义列表”
script: 'index.js'
- PM2 启动时执行的入口。
- 等价于:
node index.js(默认 interpreter 是 node)
watch: '.'
- 监控当前目录(
.)文件变化,变了就自动重启进程。 - 这是开发友好,但生产通常不建议开:日志文件、临时文件、上传文件、构建产物变化都可能触发重启,造成抖动。
- 生产建议:
watch: false或者精确 watch 某些源码目录 + ignore。
script: './service-worker/'
- 这里 PM2 猜测你可能有一个独立服务(比如一个目录下的 worker)。
- 但注意:script 通常应该指向“可执行入口文件”,比如
./service-worker/index.js。 - 如果你写的是目录,PM2/Node 未必能正确启动(取决于该目录是否有
package.json的 main 或 index.js 等)。生产里建议你明确写成:script: "./service-worker/index.js"或script: "service-worker/dist/worker.js"之类。
watch: ['./service-worker'] 监控 service-worker 目录变化自动重启这个进程(同样生产一般关掉或谨慎设置)。
deploy: { production: {...} } 是“PM2 的远程部署系统
这一块很多人不用(因为现在更常见 GitHub Actions / Jenkins / Ansible / Docker / k8s),但它确实是 PM2 自带的“一键部署”能力:你在本地运行 pm2 deploy ecosystem.config.js production,PM2 会 SSH 到服务器,拉代码、装依赖、跑 post-deploy 脚本。
PM2 的 deploy 在现代团队里基本被 CI/CD(GitHub Actions / GitLab CI / Jenkins)取代了。原因很简单:CI 更好审计、更安全(权限与密钥管理)、更容易做多环境、多步骤(测试/构建/制品/回滚)、也更符合现在的发布链路。
生产级 ecosystem.config.js 示例
/**
* PM2 配置文件:ecosystem.config.js
* 推荐把它跟项目代码一起放仓库,方便追踪与回滚。
*/
module.exports = {
/**
* apps: 进程应用列表(可以配置多个应用)
*/
apps: [
{
/**
* name: 在 pm2 里显示的应用名
*/
name: "myapp",
/**
* cwd: 工作目录(非常推荐写死,避免你从别的目录启动时路径错乱)
*/
cwd: "/var/www/myapp",
/**
* script: 入口文件(推荐 node 直接跑编译后的产物,如 dist/index.js)
* 你按自己项目入口改:
* - 纯 JS:server.js / app.js
* - TS 编译后:dist/index.js
*/
script: "dist/index.js",
/**
* args: 给脚本传参数(可选)
* 比如:node dist/index.js --port 3000
*/
// args: "--port 3000",
/**
* interpreter: 解释器(默认 node)
* 一般不用写,除非你要用 bun/deno 或指定 node 路径
*/
// interpreter: "node",
/**
* instances: 实例数
* - "max":按 CPU 核心数开满(推荐用于无状态 Web 服务)
* - 1:单实例(适合有状态/占资源大/不支持多实例的服务)
*/
instances: "max",
/**
* exec_mode:
* - "cluster":集群模式(推荐用于 Web 服务,提高吞吐与容灾)
* - "fork":单进程模式
*/
exec_mode: "cluster",
/**
* watch: 是否监控文件变更自动重启
* 生产环境一般关闭(false),避免日志/临时文件触发重启
*/
watch: false,
/**
* autorestart: 异常退出后自动重启(生产建议开启)
*/
autorestart: true,
/**
* max_restarts: 最大重启次数(避免反复崩溃死循环)
*/
max_restarts: 10,
/**
* restart_delay: 每次重启延迟(毫秒)
*/
restart_delay: 2000,
/**
* min_uptime: 进程存活小于这个时间就算“启动失败”
* 配合 max_restarts 防止一直抖动
*/
min_uptime: "10s",
/**
* max_memory_restart: 超过内存阈值自动重启(防止内存泄漏拖垮机器)
* 根据你机器内存调整,比如 300M/512M/1G
*/
max_memory_restart: "512M",
/**
* env: 默认环境变量(相当于开发/默认)
*/
env: {
NODE_ENV: "production",
PORT: 3000,
},
/**
* env_production: 生产环境变量(使用 --env production 时生效)
*/
env_production: {
NODE_ENV: "production",
PORT: 3000,
},
/**
* out_file / error_file: 标准输出 / 错误输出日志文件
* 推荐统一放到 /var/log/pm2/ 或项目 logs/ 目录
*/
out_file: "/var/log/pm2/myapp-out.log",
error_file: "/var/log/pm2/myapp-err.log",
/**
* merge_logs: 多实例时合并日志到同一文件(方便查看)
*/
merge_logs: true,
/**
* log_date_format: 日志时间格式
*/
log_date_format: "YYYY-MM-DD HH:mm:ss.SSS",
/**
* time: 给 pm2 log 增加时间戳(可选)
*/
time: true,
},
],
};日志目录别忘了建
用配置文件启动
启动
cd /var/www/myapp
pm2 start ecosystem.config.js --env production查看状态
pm2 ls
pm2 status看日志
pm2 logs myapp
# 或只看最近 200 行
pm2 logs myapp --lines 200优雅重载
代码更新,然后:
方式 A:reload(推荐,尽量不停机)
pm2 reload ecosystem.config.js --env production方式 B:restart(会中断更明显)
pm2 restart ecosystem.config.js --env production开机自启
PM2 提供 systemd 集成:
pm2 startup它会输出一条 需要你复制执行的 sudo 命令(照着执行即可)。
然后保存当前进程列表:
pm2 save验证重启后是否自动起来:
sudo reboot # 服务器会立刻重启
# 重连后
pm2 ls常用命令速查
进程管理
pm2 ls # 列表
pm2 describe myapp # 详细信息
pm2 stop myapp # 停止
pm2 start myapp # 启动(已存在配置/记录时)
pm2 restart myapp # 重启
pm2 reload myapp # 优雅重载(集群推荐)
pm2 delete myapp # 删除进程记录配置文件方式(更推荐)
pm2 start ecosystem.config.js --env production
pm2 reload ecosystem.config.js --env production
pm2 restart ecosystem.config.js --env production
pm2 delete ecosystem.config.js日志与监控
pm2 logs myapp --lines 200
pm2 monit # 交互式监控(CPU/内存/重启次数)保存与恢复(自启相关)
pm2 save # 保存当前进程列表(dump)
pm2 resurrect # 从 dump 恢复PM2 日志轮转
pm2 install pm2-logrotate
pm2 set pm2-logrotate:max_size 50M
pm2 set pm2-logrotate:retain 10
pm2 set pm2-logrotate:compress true生产实践建议
- script 指向真实入口文件(如 dist/index.js),尽量别用
npm run start包一层(除非必须)。 - cluster + instances=max 适合无状态 Web 服务;如果你有定时任务/队列消费者,可能要 fork + 单实例,或拆成第二个 app。
- max_memory_restart 强烈建议设置。
一键上线
npm i -g pm2
cd /var/www/myapp
pm2 ecosystem # 生成配置,按需修改 script/cwd/env/log
sudo mkdir -p /var/log/pm2
sudo chown -R $USER:$USER /var/log/pm2
pm2 start ecosystem.config.js --env production
pm2 ls
pm2 logs myapp --lines 200
pm2 startup
# 执行它提示你的那条 sudo 命令
pm2 save