PM2 进程管理使用教程
1. PM2 是什么
PM2 是 Node.js 应用常用的进程守护工具。
它主要解决:
- SSH 断开后,服务不会停止。
- 服务器重启后,可以自动恢复服务。
- 可以方便查看日志。
- 可以一键启动、停止、重启、删除进程。
- 适合管理 Express、Next.js、Nuxt、Vite SSR、普通 Node 后端等应用。
可以把 PM2 理解成:
1Node 应用进程管家
2. 安装 PM2
全局安装:
1npm install -g pm2
检查版本:
1pm2 -v
3. PM2 基本概念
PM2 里的每个应用都是一个进程。
例如:
1my-app 2blog 3api-server 4admin-panel
常见状态:
1online 正在运行 2stopped 已停止 3errored 启动失败或运行异常
查看所有进程:
1pm2 list
示例:
1┌────┬────────────┬─────────┬────────┬─────┬──────┬────────┐ 2│ id │ name │ mode │ status │ cpu │ mem │ user │ 3├────┼────────────┼─────────┼────────┼─────┼──────┼────────┤ 4│ 0 │ my-app │ fork │ online │ 0% │ 60mb │ root │ 5│ 1 │ api-server │ fork │ online │ 0% │ 80mb │ root │ 6└────┴────────────┴─────────┴────────┴─────┴──────┴────────┘
4. 启动一个 Node 应用
假设项目目录:
1/var/www/my-app
进入项目:
1cd /var/www/my-app
安装依赖:
1npm install
如果是需要构建的项目:
1npm run build
启动入口文件:
1pm2 start server/index.js --name my-app
如果入口是 app.js:
1pm2 start app.js --name my-app
如果需要运行 npm script:
1pm2 start npm --name my-app -- run start
5. 带环境变量启动
有些应用需要设置端口、数据库地址、密钥等环境变量。
临时写法:
1PORT=3000 \ 2NODE_ENV=production \ 3pm2 start server/index.js --name my-app
更多变量示例:
1PORT=3000 \ 2NODE_ENV=production \ 3DATABASE_URL='数据库连接地址' \ 4JWT_SECRET='一串很长的随机字符串' \ 5pm2 start server/index.js --name my-app
如果环境变量很多,推荐使用 ecosystem 配置文件,见后文。
6. 查看进程状态
查看所有进程:
1pm2 list
查看某个进程详情:
1pm2 show my-app
或者:
1pm2 describe my-app
可以看到:
- 进程状态
- 启动路径
- 脚本路径
- 日志路径
- 重启次数
- 内存占用
- 环境变量
7. 查看日志
查看某个应用日志:
1pm2 logs my-app
只看最近 100 行:
1pm2 logs my-app --lines 100
查看所有应用日志:
1pm2 logs
清空日志:
1pm2 flush
服务启动失败时,第一时间查看:
1pm2 logs my-app --lines 100
8. 停止、启动、重启、删除进程
停止:
1pm2 stop my-app
启动已停止的进程:
1pm2 start my-app
重启:
1pm2 restart my-app
平滑重载,适合部分支持 reload 的应用:
1pm2 reload my-app
删除:
1pm2 delete my-app
删除后,PM2 不再管理这个进程。
9. 保存进程列表
PM2 当前运行的进程列表不会自动永久保存。
启动好应用后执行:
1pm2 save
推荐习惯:
1pm2 start server/index.js --name my-app 2pm2 save
新增、删除、调整 PM2 进程后,也建议执行:
1pm2 save
10. 设置开机自启
执行:
1pm2 startup
PM2 会输出一行命令,类似:
1sudo env PATH=$PATH:/usr/bin pm2 startup systemd -u root --hp /root
复制它输出的那一行命令并执行。
然后保存当前进程:
1pm2 save
完整流程:
1pm2 startup 2# 复制 PM2 输出的 sudo 命令并执行 3pm2 save
检查开机自启服务:
1systemctl status pm2-root
如果不是 root 用户,服务名可能是:
1pm2-用户名
11. 更新项目代码后的操作
进入项目:
1cd /var/www/my-app
拉取代码:
1git pull
更新依赖:
1npm install
重新构建:
1npm run build
重启服务:
1pm2 restart my-app
查看状态:
1pm2 list
查看日志:
1pm2 logs my-app --lines 100
通用更新流程:
1cd /var/www/my-app 2git pull 3npm install 4npm run build 5pm2 restart my-app 6pm2 list
如果项目不需要构建,可以省略:
1npm run build
12. 修改环境变量后怎么办
如果只是更新代码,一般:
1pm2 restart my-app
如果修改了启动时传入的环境变量,最稳妥的方式是删除旧进程再重新启动:
1pm2 delete my-app
重新启动:
1PORT=3000 \ 2NODE_ENV=production \ 3pm2 start server/index.js --name my-app
保存:
1pm2 save
如果使用 ecosystem 配置文件,修改配置后可以:
1pm2 restart my-app --update-env
13. 配合 Nginx 使用
PM2 管应用进程,Nginx 管公网入口。
推荐结构:
1用户浏览器 2 ↓ 3Nginx 80/443 4 ↓ 5127.0.0.1:3000 6 ↓ 7PM2 管理的 Node 应用
检查应用是否监听:
1sudo ss -lntp | grep 3000
检查 Nginx:
1sudo nginx -t 2sudo systemctl reload nginx
如果网页出现 502,优先检查:
1pm2 list 2pm2 logs my-app --lines 100 3sudo ss -lntp | grep 3000 4sudo nginx -t
14. 常见问题排查
进程状态是 errored
查看日志:
1pm2 logs my-app --lines 100
常见原因:
- 端口被占用。
- 依赖没有安装。
- 构建产物不存在。
- 环境变量缺失。
- 文件路径不对。
- 数据库或外部服务连接失败。
端口被占用
查看谁占用了端口:
1sudo ss -lntp | grep 3000
如果是旧进程,先看 PM2:
1pm2 list
如果不是 PM2 管的进程,谨慎停止:
1sudo kill -9 进程PID
SSH 退出后服务没了
说明可能是手动运行了:
1npm run start
应该改用 PM2:
1pm2 start npm --name my-app -- run start 2pm2 save
服务器重启后服务没恢复
检查是否设置过:
1pm2 startup 2pm2 save
查看 PM2 自启服务:
1systemctl status pm2-root
日志太大
清空当前日志:
1pm2 flush
也可以安装日志轮转插件:
1pm2 install pm2-logrotate
15. ecosystem 配置方式
如果环境变量很多,推荐使用 PM2 配置文件。
新建:
1ecosystem.config.cjs
示例:
1module.exports = { 2 apps: [ 3 { 4 name: "my-app", 5 script: "server/index.js", 6 cwd: "/var/www/my-app", 7 env: { 8 NODE_ENV: "production", 9 PORT: "3000", 10 DATABASE_URL: "数据库连接地址", 11 JWT_SECRET: "一串很长的随机字符串", 12 }, 13 }, 14 ], 15};
启动:
1pm2 start ecosystem.config.cjs 2pm2 save
重启:
1pm2 restart my-app
环境变量变更后重启:
1pm2 restart my-app --update-env
注意:如果配置文件里包含密码、密钥、数据库地址,不要提交到公开仓库。
16. 多应用配置示例
1module.exports = { 2 apps: [ 3 { 4 name: "web", 5 script: "server/index.js", 6 cwd: "/var/www/web", 7 env: { 8 NODE_ENV: "production", 9 PORT: "3000", 10 }, 11 }, 12 { 13 name: "api", 14 script: "app.js", 15 cwd: "/var/www/api", 16 env: { 17 NODE_ENV: "production", 18 PORT: "4000", 19 }, 20 }, 21 ], 22};
启动所有应用:
1pm2 start ecosystem.config.cjs 2pm2 save
17. 常用命令速查
1pm2 list 2pm2 show my-app 3pm2 logs my-app 4pm2 logs my-app --lines 100 5pm2 restart my-app 6pm2 reload my-app 7pm2 stop my-app 8pm2 start my-app 9pm2 delete my-app 10pm2 save 11pm2 startup 12pm2 flush 13pm2 install pm2-logrotate