使用 pm2 守护脚本进程

C. Qiu 于 2025-03-01 发布

最近折腾某 Node.js 项目,通过 SSH 在服务器运行一 bash 脚本来启动前端应用,并希望它保持长期运行。

然而,当断开 SSH 连接时,该进程一并被关闭,造成困扰。这是因为通过 SSH 连接运行一个 bash 脚本 (start.sh) 时,这个脚本是作为 SSH 会话的一个子进程在终端中运行的。SSH 断开时,系统会向所有与该终端关联的进程发送一个 SIGHUP (Hangup) 信号。

并没有用上的 nohup 命令

一般来说 nohup 可以让脚本在 SSH 断开后继续运行:

# 基本用法
nohup ./start.sh &

# 指定输出日志文件
nohup ./start.sh > myapp.log 2>&1 &

尽管 nohup 命令简单好用,但进程管理相对基础,查看实时输出不方便。并且由 bash 脚本启动的 Node.js 进程仍会在 20 分钟后诡异地自动停止。

天然优势的 Node.js 进程管理器 PM2

PM2 是一个非常流行的 Node.js 进程管理器,具有我看重的许多优点:

维持前端应用稳定运行,这正是我需要的。

如何使用 PM2 管理进程

以 SillyTavern 为例:

  1. 安装 PM2 (需要 Node.js 和 npm):
    npm install pm2 -g
    
  2. 使用 PM2 启动 start.sh: 进入脚本所在目录,然后执行:
    cd /root/SillyTavern/
    pm2 start ./start.sh --name SillyTavern
    
    • --name SillyTavern:仅仅是起个名
  3. PM2 常用命令
    • 查看所有应用状态:pm2 listpm2 status
    • 查看特定应用日志:pm2 logs SillyTavern
    • 停止应用:pm2 stop SillyTavern
    • 重启应用:pm2 restart SillyTavern
    • 删除应用(从 PM2 列表中):pm2 delete SillyTavern
  4. 设置开机自启
    • 让 PM2 生成启动脚本(它会根据你的系统给出具体命令):
      pm2 startup
      

      按照提示复制并执行它输出的那条命令。

    • 保存当前 PM2 管理的进程列表,以便开机时恢复:
      pm2 save
      

现在 SillyTavern 服务就由 PM2 守护了。它会在后台稳定运行,即使 SSH 断开,或是服务器重启(当然,pm2 startuppm2 save要配置正确)。

更新应用时,先停止应用pm2 stop SillyTavern,更新文件 (对于我,直接git pull),然后pm2 restart SillyTavern

总结

需要在 SSH 断开后保持脚本运行时,对于简单脚本,nohup可能就够了。

对于需要交互或更复杂管理的场景,也可以使用screentmux等。但如果需要更健壮、功能更全面的进程管理,特别是针对 Node.js 写的屎山项目 SillyTavern,PM2 无疑是更优选择。