PortOS uses a contiguous port allocation scheme to make it easy to understand which ports are in use and which are available.
- Contiguous Ranges: Each app should use a contiguous block of ports
- Labeled Ports: Use the
portsobject inecosystem.config.cjsto define all ports with descriptive labels - No Gaps: Avoid leaving gaps between port allocations within an app
Common port labels:
api- REST API serverui- Web UI / frontendcdp- Chrome DevTools Protocolhealth- Health check endpointws- WebSocket server
| Port | Process | Label | Description |
|---|---|---|---|
| 5554 | portos-client | ui | Vite dev server (React UI) |
| 5555 | portos-server | api | Main API server |
| 5556 | portos-browser | cdp | Chrome DevTools Protocol |
| 5557 | portos-browser | health | Browser health check API |
| 5558 | portos-cos | api | CoS Agent Runner (isolated process) |
| 5559 | portos-autofixer | api | Autofixer daemon API |
| 5560 | portos-autofixer-ui | ui | Autofixer web UI |
| 5561 | portos-db | db | PostgreSQL + pgvector (Docker, memory system) |
Define all ports in a top-level PORTS object as the single source of truth:
// =============================================================================
// Port Configuration - All ports defined here as single source of truth
// =============================================================================
const PORTS = {
API: 5570, // REST API server
UI: 5571, // Web UI
CDP: 5572 // Chrome DevTools Protocol
};
module.exports = {
PORTS, // Export for other configs to reference
apps: [
{
name: 'my-api',
script: 'server.js',
env: {
PORT: PORTS.API
}
},
{
name: 'my-ui',
script: 'node_modules/.bin/vite',
args: `--port ${PORTS.UI}`,
env: {
VITE_PORT: PORTS.UI
}
}
]
};- Single Source of Truth: Each port defined once
- Importable: Other configs can
require('./ecosystem.config.cjs').PORTS - Clear Comments: Document what each port is for
- DRY: No duplication between
portsobject andenvvars
PortOS automatically detects ports from env vars:
PORT→ labeled asapi(oruifor-ui/-clientprocesses,healthfor-browserprocesses with CDP)CDP_PORT→ labeled ascdpVITE_PORT→ labeled asui--portin args → labeled asui
- Check Available Ports: Use PortOS apps list to see which ports are in use
- Pick a Contiguous Range: Choose a starting port and allocate contiguously
- Define PORTS Object: Always define ports in a top-level
PORTSconstant - Avoid Common Ports: Stay away from well-known ports (80, 443, 3000, 8080, etc.)
| Range | Purpose |
|---|---|
| 5554-5560 | PortOS core services |
| 5561-5569 | Reserved for PortOS extensions |
| 5570-5599 | User applications |
The PortOS apps list shows all ports for each process:
- Single port:
process-name:5555 - Multiple ports:
process-name (cdp:5556,health:5557)
Use the API to get detailed port information:
curl http://localhost:5555/api/apps | jq '.[].processes'