-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathecosystem.config.cjs
More file actions
159 lines (154 loc) · 5.18 KB
/
ecosystem.config.cjs
File metadata and controls
159 lines (154 loc) · 5.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
// =============================================================================
// PM2 Ecosystem Configuration - shared constants and app definitions
// =============================================================================
const path = require('path');
const LOG_DATE_FORMAT = 'YYYY-MM-DDTHH:mm:ss.SSS[Z]';
const IS_WIN = process.platform === 'win32';
// Shared env inherited by all apps (merged into each app's env)
const BASE_ENV = {
NODE_ENV: 'development',
TZ: 'UTC' // All log timestamps and Date operations in UTC
};
// Read PGMODE from .env to determine PostgreSQL port
const fs = require('fs');
const envFile = path.join(__dirname, '.env');
let pgMode = 'docker';
try {
const envContent = fs.readFileSync(envFile, 'utf8');
const modeMatch = envContent.match(/^PGMODE=(\w+)/m);
if (modeMatch) pgMode = modeMatch[1];
} catch { /* no .env file — default to docker */ }
const PORTS = {
API: 5555, // Express API server (HTTPS when Tailscale cert is active)
API_LOCAL: 5553, // Loopback-only HTTP mirror of API — only binds when HTTPS is active on :API.
// Lets http://localhost work without cert warnings. Override w/ PORTOS_HTTP_PORT.
UI: 5554, // Vite dev server (client)
CDP: 5556, // Chrome DevTools Protocol (browser automation)
CDP_HEALTH: 5557, // Browser health check endpoint
COS: 5558, // Chief of Staff agent runner
AUTOFIXER: 5559, // Autofixer API
AUTOFIXER_UI: 5560, // Autofixer UI
POSTGRES_DOCKER: 5561, // PostgreSQL Docker container (host port mapping)
POSTGRES: pgMode === 'native' ? 5432 : 5561 // Active PostgreSQL port (unused in file mode)
};
module.exports = {
PORTS, // Export for other configs to reference
apps: [
{
name: 'portos-server',
script: 'server/index.js',
cwd: __dirname,
interpreter: 'node',
log_date_format: LOG_DATE_FORMAT,
windowsHide: IS_WIN,
env: {
...BASE_ENV,
PORT: PORTS.API,
PORTOS_HTTP_PORT: PORTS.API_LOCAL, // Loopback HTTP mirror when HTTPS is active
HOST: '0.0.0.0',
PGPORT: PORTS.POSTGRES,
PGPASSWORD: process.env.PGPASSWORD || 'portos',
...(pgMode === 'file' ? { MEMORY_BACKEND: 'file' } : {}),
PATH: process.env.PATH // Inherit PATH for git/node access in child processes
},
watch: ['server'],
watch_delay: 300000, // 5 min delay before restarting on file changes
ignore_watch: ['**/node_modules', '**/*.test.js', '**/*package-lock*'],
max_memory_restart: '2G'
},
{
name: 'portos-cos',
script: 'server/cos-runner/index.js',
cwd: __dirname,
interpreter: 'node',
log_date_format: LOG_DATE_FORMAT,
windowsHide: IS_WIN,
// CoS Agent Runner - isolated process for spawning Claude CLI agents
// Does NOT restart when portos-server restarts, preventing orphaned agents
// Security: Binds to localhost only - not exposed externally
env: {
...BASE_ENV,
PORT: PORTS.COS,
HOST: '127.0.0.1'
},
watch: false,
autorestart: true,
max_restarts: 5,
min_uptime: '30s',
restart_delay: 10000,
max_memory_restart: '2G',
// Important: This process manages long-running agent processes
// Keep kill_timeout high to allow graceful shutdown of agents
kill_timeout: 30000
},
{
name: 'portos-ui',
script: path.join(__dirname, 'client', 'node_modules', 'vite', 'bin', 'vite.js'),
cwd: path.join(__dirname, 'client'),
log_date_format: LOG_DATE_FORMAT,
windowsHide: IS_WIN,
args: `--host 0.0.0.0 --port ${PORTS.UI}`,
env: {
...BASE_ENV,
VITE_PORT: PORTS.UI
},
watch: false
},
{
name: 'portos-autofixer',
script: 'autofixer/server.js',
cwd: __dirname,
interpreter: 'node',
log_date_format: LOG_DATE_FORMAT,
windowsHide: IS_WIN,
env: {
...BASE_ENV,
PORT: PORTS.AUTOFIXER,
PATH: process.env.PATH // Inherit PATH for nvm/node access in child processes
},
watch: false,
autorestart: true,
max_restarts: 10,
min_uptime: '10s',
restart_delay: 5000
},
{
name: 'portos-autofixer-ui',
script: 'autofixer/ui.js',
cwd: __dirname,
interpreter: 'node',
log_date_format: LOG_DATE_FORMAT,
windowsHide: IS_WIN,
env: {
...BASE_ENV,
PORT: PORTS.AUTOFIXER_UI
},
watch: false,
autorestart: true,
max_restarts: 10,
min_uptime: '10s',
restart_delay: 5000
},
{
name: 'portos-browser',
script: 'browser/server.js',
cwd: __dirname,
interpreter: 'node',
log_date_format: LOG_DATE_FORMAT,
windowsHide: IS_WIN,
// Security: CDP binds to 127.0.0.1 by default (set CDP_HOST=0.0.0.0 to expose)
// Remote access should go through portos-server proxy with authentication
env: {
...BASE_ENV,
CDP_PORT: PORTS.CDP,
CDP_HOST: '127.0.0.1',
PORT: PORTS.CDP_HEALTH
},
watch: false,
autorestart: true,
max_restarts: 10,
min_uptime: '10s',
restart_delay: 5000
}
]
};