pm2

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

PM2 — Process Manager

PM2 — 进程管理器

PM2 keeps processes alive, restarts them on crash, and provides monitoring/logging. Use for long-running services, persistent agents, background workers.
Not for detached terminals — use holdpty when you need PTY output, attach/view, or interactive sessions. Not for ephemeral tasks — use
pi -p > file &
for quick fire-and-forget agent runs.
PM2 可保持进程持续运行,进程崩溃时自动重启,并提供监控与日志功能。 适用于长期运行的服务、持久化Agent、后台工作进程。
不适合用于分离终端场景——当你需要PTY输出、附加/查看或交互式会话时,请使用holdpty不适合用于临时任务——快速执行即弃的Agent运行请使用
pi -p > file &

Quick Reference

快速参考

Start a process

启动进程

bash
undefined
bash
undefined

Simple

Simple

pm2 start server.js --name myapp
pm2 start server.js --name myapp

With interpreter

With interpreter

pm2 start script.py --interpreter python3 --name worker
pm2 start script.py --interpreter python3 --name worker

With arguments (use -- to separate pm2 args from script args)

With arguments (use -- to separate pm2 args from script args)

pm2 start app.js --name api -- --port 3000 --env production
pm2 start app.js --name api -- --port 3000 --env production

From ecosystem file

From ecosystem file

pm2 start ecosystem.config.cjs
undefined
pm2 start ecosystem.config.cjs
undefined

Manage processes

管理进程

bash
pm2 list                    # List all processes (table)
pm2 jlist                   # List as JSON (for scripting)
pm2 info <name|id>          # Detailed process info
pm2 restart <name|id|all>   # Restart
pm2 stop <name|id|all>      # Stop (keeps in list)
pm2 delete <name|id|all>    # Stop + remove from list
pm2 restart <name> --update-env  # Restart with refreshed env vars
bash
pm2 list                    # List all processes (table)
pm2 jlist                   # List as JSON (for scripting)
pm2 info <name|id>          # Detailed process info
pm2 restart <name|id|all>   # Restart
pm2 stop <name|id|all>      # Stop (keeps in list)
pm2 delete <name|id|all>    # Stop + remove from list
pm2 restart <name> --update-env  # Restart with refreshed env vars

Logs

日志

bash
pm2 logs                     # Tail all logs
pm2 logs <name> --lines 50   # Tail specific process, last 50 lines
pm2 flush                    # Clear all log files
Log files location:
~/.pm2/logs/<name>-out.log
and
<name>-error.log
.
bash
pm2 logs                     # Tail all logs
pm2 logs <name> --lines 50   # Tail specific process, last 50 lines
pm2 flush                    # Clear all log files
日志文件位置:
~/.pm2/logs/<name>-out.log
<name>-error.log

Monitoring

监控

bash
pm2 monit          # Real-time TUI: CPU, memory, logs
pm2 dash           # Dashboard with monitoring + logs
bash
pm2 monit          # Real-time TUI: CPU, memory, logs
pm2 dash           # Dashboard with monitoring + logs

Ecosystem Config

生态系统配置

For reproducible multi-process setups, use an
ecosystem.config.cjs
file:
javascript
// ecosystem.config.cjs
module.exports = {
  apps: [
    {
      name: "api",
      script: "dist/server.js",
      instances: 2,                // cluster mode
      exec_mode: "cluster",
      env: {
        NODE_ENV: "production",
        PORT: 3000,
      },
      max_memory_restart: "500M",
      log_date_format: "YYYY-MM-DD HH:mm:ss",
    },
    {
      name: "worker",
      script: "dist/worker.js",
      autorestart: true,
      max_restarts: 10,
      restart_delay: 5000,
      exp_backoff_restart_delay: 100,  // exponential backoff
      watch: false,
    },
  ],
};
bash
pm2 start ecosystem.config.cjs           # Start all apps
pm2 start ecosystem.config.cjs --only api  # Start specific app
pm2 restart ecosystem.config.cjs          # Restart all
pm2 delete ecosystem.config.cjs           # Stop + remove all
对于可复现的多进程部署,请使用
ecosystem.config.cjs
文件:
javascript
// ecosystem.config.cjs
module.exports = {
  apps: [
    {
      name: "api",
      script: "dist/server.js",
      instances: 2,                // cluster mode
      exec_mode: "cluster",
      env: {
        NODE_ENV: "production",
        PORT: 3000,
      },
      max_memory_restart: "500M",
      log_date_format: "YYYY-MM-DD HH:mm:ss",
    },
    {
      name: "worker",
      script: "dist/worker.js",
      autorestart: true,
      max_restarts: 10,
      restart_delay: 5000,
      exp_backoff_restart_delay: 100,  // exponential backoff
      watch: false,
    },
  ],
};
bash
pm2 start ecosystem.config.cjs           # Start all apps
pm2 start ecosystem.config.cjs --only api  # Start specific app
pm2 restart ecosystem.config.cjs          # Restart all
pm2 delete ecosystem.config.cjs           # Stop + remove all

Useful ecosystem options

实用的生态系统配置选项

OptionTypeDescription
script
stringScript to run (required)
interpreter
stringOverride interpreter (default:
node
)
args
string or string[]Script arguments
cwd
stringWorking directory
instances
numberNumber of instances (cluster mode)
exec_mode
string
"fork"
(default) or
"cluster"
autorestart
booleanAuto-restart on exit (default:
true
)
max_restarts
numberMax consecutive restarts before stopping
restart_delay
numberDelay between restarts (ms)
exp_backoff_restart_delay
numberExponential backoff base (ms)
max_memory_restart
stringRestart if memory exceeds (e.g.
"500M"
)
cron_restart
stringCron-based restart schedule
watch
boolean or string[]Watch for file changes
ignore_watch
string[]Paths to ignore when watching
env
objectEnvironment variables
log_date_format
stringTimestamp format for logs
error_file
stringCustom stderr log path
out_file
stringCustom stdout log path
merge_logs
booleanMerge cluster instance logs
stop_exit_codes
number[]Exit codes that skip auto-restart
选项类型描述
script
string要运行的脚本(必填)
interpreter
string覆盖默认解释器(默认:
node
args
string 或 string[]脚本参数
cwd
string工作目录
instances
number实例数量(集群模式)
exec_mode
string
"fork"
(默认)或
"cluster"
autorestart
boolean进程退出时自动重启(默认:
true
max_restarts
number停止前允许的最大连续重启次数
restart_delay
number重启间隔时间(毫秒)
exp_backoff_restart_delay
number指数退避的基础间隔(毫秒)
max_memory_restart
string内存超过阈值时重启(例如
"500M"
cron_restart
string基于Cron表达式的重启计划
watch
boolean 或 string[]监听文件变化
ignore_watch
string[]监听时忽略的路径
env
object环境变量
log_date_format
string日志时间戳格式
error_file
string自定义标准错误日志路径
out_file
string自定义标准输出日志路径
merge_logs
boolean合并集群实例日志
stop_exit_codes
number[]无需自动重启的退出码

Persistence

持久化

bash
pm2 save               # Save current process list
pm2 resurrect           # Restore saved process list
pm2 startup             # Generate OS startup script (auto-start on boot)
pm2 unstartup           # Remove startup script
After
pm2 startup
, run the command it outputs (may need admin/sudo). Then
pm2 save
to snapshot current processes — they'll auto-start on reboot.
bash
pm2 save               # Save current process list
pm2 resurrect           # Restore saved process list
pm2 startup             # Generate OS startup script (auto-start on boot)
pm2 unstartup           # Remove startup script
执行
pm2 startup
后,运行其输出的命令(可能需要管理员/ sudo权限)。 然后执行
pm2 save
保存当前进程快照——系统重启时这些进程会自动启动。

Windows Gotchas

Windows注意事项

.cmd
wrapper resolution

.cmd 包装器解析

PM2 tries to run
.cmd
files as Node.js scripts. Never start a
.cmd
shim directly
with PM2.
bash
undefined
PM2 会尝试将
.cmd
文件作为Node.js脚本运行。切勿直接使用PM2启动.cmd脚本
bash
undefined

❌ WRONG — resolves to pi.cmd, crashes

❌ 错误方式——会解析为pi.cmd,导致崩溃

pm2 start pi -- -p "prompt"
pm2 start pi -- -p "prompt"

✅ CORRECT — point to the actual .js entry point

✅ 正确方式——指向实际的.js入口文件

pm2 start /path/to/cli.js --interpreter node -- -p "prompt"

For npm-installed CLIs, find the real script:

```bash
pm2 start /path/to/cli.js --interpreter node -- -p "prompt"

对于通过npm安装的CLI工具,找到其真实脚本路径:

```bash

Find where the .cmd shim points

查找.cmd脚本指向的路径

cat "$(which pi)" | head -5
cat "$(which pi)" | head -5

→ Look for the .js path, then use that with --interpreter node

→ 找到.js路径后,结合--interpreter node使用


In ecosystem configs, always use the resolved `.js` path:

```javascript
module.exports = {
  apps: [{
    name: "my-agent",
    // Resolve the actual cli.js, not the .cmd wrapper
    script: "C:\\path\\to\\node_modules\\package\\dist\\cli.js",
    interpreter: "node",
    args: ["--mode", "json"],
  }],
};

在生态系统配置中,请始终使用解析后的.js路径:

```javascript
module.exports = {
  apps: [{
    name: "my-agent",
    // 指向实际的cli.js,而非.cmd包装器
    script: "C:\\path\\to\\node_modules\\package\\dist\\cli.js",
    interpreter: "node",
    args: ["--mode", "json"],
  }],
};

Log paths

日志路径

PM2 stores logs at
~/.pm2/logs/
. On Windows this is typically
C:\Users\<user>\.pm2\logs\
.
PM2 将日志存储在
~/.pm2/logs/
目录下。在Windows系统中,通常路径为
C:\Users\<user>\.pm2\logs\

Daemon

守护进程

PM2 daemon runs as a background Node.js process.
pm2 kill
stops the daemon and all managed processes.
pm2 ping
checks if the daemon is running.
PM2 守护进程作为后台Node.js进程运行。
pm2 kill
会停止守护进程及所有受管理的进程。
pm2 ping
用于检查守护进程是否运行。

Agent Patterns

Agent模式

Launch a pi agent as a persistent service

将pi agent作为持久化服务启动

First, find the actual
cli.js
path (see Windows Gotchas above):
bash
undefined
首先,找到实际的
cli.js
路径(参考上述Windows注意事项):
bash
undefined

Find pi's real entry point

查找pi的真实入口文件

cat "$(which pi)" | head -5
cat "$(which pi)" | head -5

e.g. → /path/to/node_modules/@mariozechner/pi-coding-agent/dist/cli.js

例如 → /path/to/node_modules/@mariozechner/pi-coding-agent/dist/cli.js


```javascript
// ecosystem.config.cjs
module.exports = {
  apps: [{
    name: "my-agent",
    // Use the resolved cli.js path — NOT the .cmd wrapper
    script: "/path/to/node_modules/@mariozechner/pi-coding-agent/dist/cli.js",
    interpreter: "node",
    args: ["--mode", "json", "--cwd", "/path/to/project"],
    autorestart: true,
    max_restarts: 10,
    restart_delay: 5000,
  }],
};
Note:
pi -p
to non-TTY only outputs final text. Use
--mode json
for full event streaming to PM2 logs.

```javascript
// ecosystem.config.cjs
module.exports = {
  apps: [{
    name: "my-agent",
    // 使用解析后的cli.js路径——而非.cmd包装器
    script: "/path/to/node_modules/@mariozechner/pi-coding-agent/dist/cli.js",
    interpreter: "node",
    args: ["--mode", "json", "--cwd", "/path/to/project"],
    autorestart: true,
    max_restarts: 10,
    restart_delay: 5000,
  }],
};
注意
pi -p
在非TTY环境下仅输出最终文本。如需将完整事件流输出到PM2日志,请使用
--mode json

Check process health from an agent

从Agent检查进程健康状态

bash
undefined
bash
undefined

Structured output for parsing

结构化输出以便解析

pm2 jlist | node -e " const d = JSON.parse(require('fs').readFileSync('/dev/stdin','utf8')); d.forEach(p => console.log(p.name, p.pm2_env.status, 'restarts:', p.pm2_env.restart_time)); "
undefined
pm2 jlist | node -e " const d = JSON.parse(require('fs').readFileSync('/dev/stdin','utf8')); d.forEach(p => console.log(p.name, p.pm2_env.status, 'restarts:', p.pm2_env.restart_time)); "
undefined

Rotate logs

日志轮转

bash
pm2 install pm2-logrotate        # Install log rotation module
pm2 set pm2-logrotate:max_size 10M
pm2 set pm2-logrotate:retain 5
bash
pm2 install pm2-logrotate        # Install log rotation module
pm2 set pm2-logrotate:max_size 10M
pm2 set pm2-logrotate:retain 5

When NOT to Use PM2

不适合使用PM2的场景

  • Detached terminal sessions → use holdpty (PTY output, attach/view)
  • Ephemeral agent runs → use
    pi -p > file &
    (fire-and-forget with output capture)
  • Containers → the container runtime manages lifecycle; PM2 inside Docker is usually redundant
  • Systemd environments → use systemd service units natively on Linux
  • 分离终端会话 → 使用holdpty(支持PTY输出、附加/查看)
  • 临时Agent运行 → 使用
    pi -p > file &
    (执行即弃并捕获输出)
  • 容器环境 → 容器运行时会管理生命周期;Docker内部通常无需使用PM2
  • Systemd环境 → 在Linux系统上直接使用systemd服务单元