Loading...
Loading...
Process management with PM2 — start, stop, restart, monitor long-running processes. Use when: keeping services alive, auto-restart on crash, managing daemon processes, ecosystem configs, log management, startup scripts, process monitoring. Triggers: pm2, process manager, keep alive, daemon, auto-restart, ecosystem config, process monitoring.
npx skill4agent add marcfargas/skills pm2Not for detached terminals — use holdpty when you need PTY output, attach/view, or interactive sessions. Not for ephemeral tasks — usefor quick fire-and-forget agent runs.pi -p > file &
# Simple
pm2 start server.js --name myapp
# With interpreter
pm2 start script.py --interpreter python3 --name worker
# With arguments (use -- to separate pm2 args from script args)
pm2 start app.js --name api -- --port 3000 --env production
# From ecosystem file
pm2 start ecosystem.config.cjspm2 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 varspm2 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.logpm2 monit # Real-time TUI: CPU, memory, logs
pm2 dash # Dashboard with monitoring + logsecosystem.config.cjs// 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,
},
],
};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| Option | Type | Description |
|---|---|---|
| string | Script to run (required) |
| string | Override interpreter (default: |
| string or string[] | Script arguments |
| string | Working directory |
| number | Number of instances (cluster mode) |
| string | |
| boolean | Auto-restart on exit (default: |
| number | Max consecutive restarts before stopping |
| number | Delay between restarts (ms) |
| number | Exponential backoff base (ms) |
| string | Restart if memory exceeds (e.g. |
| string | Cron-based restart schedule |
| boolean or string[] | Watch for file changes |
| string[] | Paths to ignore when watching |
| object | Environment variables |
| string | Timestamp format for logs |
| string | Custom stderr log path |
| string | Custom stdout log path |
| boolean | Merge cluster instance logs |
| number[] | Exit codes that skip auto-restart |
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 scriptpm2 startuppm2 save.cmd.cmd.cmd# ❌ WRONG — resolves to pi.cmd, crashes
pm2 start pi -- -p "prompt"
# ✅ CORRECT — point to the actual .js entry point
pm2 start /path/to/cli.js --interpreter node -- -p "prompt"# Find where the .cmd shim points
cat "$(which pi)" | head -5
# → Look for the .js path, then use that with --interpreter node.jsmodule.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"],
}],
};~/.pm2/logs/C:\Users\<user>\.pm2\logs\pm2 killpm2 pingcli.js# Find pi's real entry point
cat "$(which pi)" | head -5
# e.g. → /path/to/node_modules/@mariozechner/pi-coding-agent/dist/cli.js// 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:to non-TTY only outputs final text. Usepi -pfor full event streaming to PM2 logs.--mode json
# 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));
"pm2 install pm2-logrotate # Install log rotation module
pm2 set pm2-logrotate:max_size 10M
pm2 set pm2-logrotate:retain 5pi -p > file &