hardware/mac-studio/services/pm2-processes.md

PM2 Processes (Mac Studio)

All long-running background services on the Mac Studio (192.168.1.189) are managed by pm2, with per-process ecosystem config files stored at:

~/Work/pm2_processes/

Each service has its own pm2.<name>.json file (pm2 "ecosystem" format — single-app object, not wrapped in apps: [...]). Related helper scripts (like PATH shims) live in ~/Work/pm2_processes/bin/.

Common commands

pm2 list                                    # see all running processes
pm2 start ~/Work/pm2_processes/pm2.<name>.json
pm2 restart <name>:<port>
pm2 delete <name>:<port>
pm2 logs <name>:<port> --lines 50 --nostream
pm2 save                                    # persist current process list (used on boot resurrect)

ppm2 (see dev/dev-server.md) is an alias pinning a specific pm2/node version — prefer it if pm2 on PATH resolves inconsistently.

Current processes

Process Port Config Purpose
cloudcli 49996 pm2.cloudcli.json cloudcli tool, forked mode
dom-dashboard 8086 pm2.dom-dashboard.json Next.js dashboard (build + start via /bin/sh -c)
nginx-auth-service 8085 pm2.nginx-auth-service.json Session-based auth for nginx auth_request — see nginx-auth-service.md
notes 8007 pm2.notes.json This personal-notes markdown viewer — see main README.md
opencode 4096 pm2.opencode.json opencode web server (see gotcha below)
pi-web 49997 pm2.pi-web.json pi-web, started with --no-open to avoid auto browser launch
pi-webui 49998 pm2.pi-webui.json pi-webui
reasonix 49999 pm2.reasonix.json reasonix code dashboard

Gotcha: opencode web always tries to open a browser

opencode web (SST's opencode CLI) hardcodes a call to the open npm package on the server's localhost URL every time it starts — there is no CLI flag or env var to suppress it (confirmed by reading sst/opencode's web.ts source: it unconditionally calls open(localhostUrl) after the server binds). Since this runs under pm2 headlessly, that meant every restart tried to pop a browser tab.

Fix: shadow the open command just for this pm2 process. open (sindresorhus/open) resolves the open binary via $PATH on macOS — it doesn't hardcode /usr/bin/open. So:

  1. Created a no-op shim at ~/Work/pm2_processes/bin/open (#!/bin/sh + exit 0, chmod +x).
  2. Prepended ~/Work/pm2_processes/bin to the PATH env var in pm2.opencode.json's env.PATH.
  3. pm2 delete opencode:4096 && pm2 start pm2.opencode.json && pm2 save.

This only affects the opencode pm2 process's child processes — doesn't touch the system-wide /usr/bin/open or any other pm2 process (e.g. pi-web uses its own real --no-open CLI flag instead, since it supports one natively).