This document describes the recommended PM2 configuration pattern for PortOS sub-projects.
PM2 is a process manager for Node.js applications. We use ecosystem.config.cjs files to define process configurations declaratively.
Use CommonJS format (.cjs) for ecosystem files to ensure compatibility across all environments:
module.exports = {
apps: [
// Process definitions go here
]
};module.exports = {
apps: [
{
name: 'my-app',
script: 'server/index.js',
cwd: __dirname,
interpreter: 'node',
ports: { api: 5570 },
env: {
NODE_ENV: 'development',
PORT: 5570,
HOST: '0.0.0.0'
},
watch: false,
max_memory_restart: '500M'
}
]
};| Field | Description |
|---|---|
name |
Unique process name (used by PM2 for identification) |
script |
Path to the entry script |
cwd |
Working directory (use __dirname for relative paths) |
| Field | Description | Default |
|---|---|---|
interpreter |
Node interpreter path | 'node' |
ports |
Port allocation object (PortOS convention) | - |
env |
Environment variables | {} |
watch |
Enable file watching | false |
max_memory_restart |
Restart if memory exceeds threshold | - |
For services that should auto-recover from failures:
{
autorestart: true,
max_restarts: 10,
min_uptime: '10s',
restart_delay: 5000
}| Field | Description |
|---|---|
autorestart |
Restart on crash |
max_restarts |
Maximum consecutive restarts before giving up |
min_uptime |
Minimum uptime before considering "stable" |
restart_delay |
Delay (ms) between restart attempts |
Define all ports in a ports object for documentation and PortOS integration:
{
name: 'my-app',
// PortOS convention: define all ports used by this process
ports: { api: 5570, health: 5571 },
env: {
PORT: 5570,
HEALTH_PORT: 5571
}
}api- REST API serverui- Web UI / frontendcdp- Chrome DevTools Protocolhealth- Health check endpointws- WebSocket server
See PORTS.md for the full port allocation guide.
{
name: 'myapp-server',
script: 'server/index.js',
cwd: __dirname,
interpreter: 'node',
ports: { api: 5570 },
env: {
NODE_ENV: 'development',
PORT: 5570,
HOST: '0.0.0.0'
},
watch: false,
max_memory_restart: '500M'
}{
name: 'myapp-client',
script: 'node_modules/.bin/vite',
cwd: `${__dirname}/client`,
args: '--host 0.0.0.0 --port 5571',
ports: { ui: 5571 },
env: {
NODE_ENV: 'development'
},
watch: false
}{
name: 'myapp-worker',
script: 'worker/index.js',
cwd: __dirname,
interpreter: 'node',
ports: {}, // No ports if internal-only
env: {
NODE_ENV: 'development'
},
watch: false,
autorestart: true,
max_restarts: 10,
min_uptime: '10s',
restart_delay: 5000
}{
name: 'myapp-browser',
script: '.browser/server.js',
cwd: __dirname,
interpreter: 'node',
ports: { cdp: 5572, health: 5573 },
env: {
NODE_ENV: 'development',
CDP_PORT: 5572,
PORT: 5573
},
watch: false,
autorestart: true,
max_restarts: 10,
min_uptime: '10s',
restart_delay: 5000
}# Start all processes defined in ecosystem file
pm2 start ecosystem.config.cjs
# Restart all processes
pm2 restart ecosystem.config.cjs
# Stop all processes
pm2 stop ecosystem.config.cjs# View process list
pm2 list
# View logs
pm2 logs
# View logs for specific process
pm2 logs myapp-server-
Never use
pm2 killorpm2 delete all- This affects all PM2 processes on the system, not just yours -
Always use ecosystem file for restart/stop operations:
pm2 restart ecosystem.config.cjs # Correct pm2 restart all # Dangerous - affects all apps
-
Use
pm2 saveafter changes to persist the process list:pm2 start ecosystem.config.cjs pm2 save
Here's a complete ecosystem file for a typical monorepo:
module.exports = {
apps: [
{
name: 'myapp-server',
script: 'server/index.js',
cwd: __dirname,
interpreter: 'node',
ports: { api: 5570 },
env: {
NODE_ENV: 'development',
PORT: 5570,
HOST: '0.0.0.0'
},
watch: false,
max_memory_restart: '500M'
},
{
name: 'myapp-client',
script: 'node_modules/.bin/vite',
cwd: `${__dirname}/client`,
args: '--host 0.0.0.0 --port 5571',
ports: { ui: 5571 },
env: {
NODE_ENV: 'development'
},
watch: false
},
{
name: 'myapp-worker',
script: 'worker/index.js',
cwd: __dirname,
interpreter: 'node',
ports: {},
env: {
NODE_ENV: 'development'
},
watch: false,
autorestart: true,
max_restarts: 10,
min_uptime: '10s',
restart_delay: 5000
}
]
};For different environments (dev/prod), use environment blocks:
{
name: 'myapp-server',
script: 'server/index.js',
env: {
NODE_ENV: 'development',
PORT: 5570
},
env_production: {
NODE_ENV: 'production',
PORT: 5570
}
}Start with specific environment:
pm2 start ecosystem.config.cjs --env productionWhen your app follows these patterns, PortOS can:
- Display port allocations in the apps list
- Track process health and memory usage
- Provide one-click restart/stop controls
- Show consolidated logs
Register your ecosystem file with PortOS to enable management features.