pm2

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.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "pm2" with this command: npx skills add marcfargas/skills/marcfargas-skills-pm2

PM2 — Process Manager

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.

Quick Reference

Start a process

# 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.cjs

Manage processes

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

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.

Monitoring

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:

// 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

Useful ecosystem options

OptionTypeDescription
scriptstringScript to run (required)
interpreterstringOverride interpreter (default: node)
argsstring or string[]Script arguments
cwdstringWorking directory
instancesnumberNumber of instances (cluster mode)
exec_modestring"fork" (default) or "cluster"
autorestartbooleanAuto-restart on exit (default: true)
max_restartsnumberMax consecutive restarts before stopping
restart_delaynumberDelay between restarts (ms)
exp_backoff_restart_delaynumberExponential backoff base (ms)
max_memory_restartstringRestart if memory exceeds (e.g. "500M")
cron_restartstringCron-based restart schedule
watchboolean or string[]Watch for file changes
ignore_watchstring[]Paths to ignore when watching
envobjectEnvironment variables
log_date_formatstringTimestamp format for logs
error_filestringCustom stderr log path
out_filestringCustom stdout log path
merge_logsbooleanMerge cluster instance logs
stop_exit_codesnumber[]Exit codes that skip auto-restart

Persistence

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.

Windows Gotchas

.cmd wrapper resolution

PM2 tries to run .cmd files as Node.js scripts. Never start a .cmd shim directly with PM2.

# ❌ 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"

For npm-installed CLIs, find the real script:

# Find where the .cmd shim points
cat "$(which pi)" | head -5
# → Look for the .js path, then use that with --interpreter node

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

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"],
  }],
};

Log paths

PM2 stores logs at ~/.pm2/logs/. On Windows this is typically 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.

Agent Patterns

Launch a pi agent as a persistent service

First, find the actual cli.js path (see Windows Gotchas above):

# 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: pi -p to non-TTY only outputs final text. Use --mode json for full event streaming to PM2 logs.

Check process health from an agent

# 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));
"

Rotate logs

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

  • 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

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

web-search

No summary provided by upstream source.

Repository SourceNeeds Review
General

gcloud

No summary provided by upstream source.

Repository SourceNeeds Review
General

vhs

No summary provided by upstream source.

Repository SourceNeeds Review
General

sheet-model

No summary provided by upstream source.

Repository SourceNeeds Review