Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,22 @@ Learn more about our design decisions and system components in the **[Architectu

---

## 🔀 Multi-Instance Development

Run multiple isolated dev instances on one machine for parallel feature work:

```bash
# Instance 0 (default)
just dev

# Instance 1 — offset ports (frontend :5273, backend :3311)
SHIPSEC_INSTANCE=1 just dev
```

Each instance gets its own frontend port, backend port, database, and Temporal namespace while sharing a single Docker infra stack. See [Multi-Instance Development Guide](docs/MULTI-INSTANCE-DEV.md) for full details.

---

## ✍️ Contributing

We welcome contributions to the management plane, worker logic, or new security components.
Expand Down
2 changes: 1 addition & 1 deletion docs/MULTI-INSTANCE-DEV.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ http://localhost:5273 # frontend
http://localhost:3311/api # backend API
```

The Vite dev server proxies `/api` calls to the correct backend port automatically via `VITE_API_URL`.
The Vite dev server proxies `/api` calls to the correct backend port automatically (computed from `SHIPSEC_INSTANCE` in `vite.config.ts`).

## Commands

Expand Down
8 changes: 6 additions & 2 deletions frontend/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import path from 'path';

const apiTarget = process.env.VITE_API_URL || 'http://localhost:3211';
const instance = parseInt(process.env.SHIPSEC_INSTANCE || '0', 10);
const frontendPort = 5173 + instance * 100;
const backendPort = 3211 + instance * 100;

// https://vitejs.dev/config/
export default defineConfig({
Expand All @@ -23,11 +25,13 @@ export default defineConfig({
},
server: {
host: '0.0.0.0',
port: frontendPort,
strictPort: true,
open: false,
allowedHosts: ['studio.shipsec.ai', 'frontend'],
proxy: {
'/api': {
target: apiTarget,
target: `http://localhost:${backendPort}`,
changeOrigin: true,
secure: false,
},
Expand Down
6 changes: 2 additions & 4 deletions pm2.config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -331,14 +331,12 @@ module.exports = {
name: `shipsec-frontend-${instanceNum}`,
cwd: __dirname + '/frontend',
script: 'bun',
// Ensure each instance binds to its own Vite port (default is 5173).
args: ['run', 'dev', '--', '--port', String(getInstancePort(5173, instanceNum)), '--strictPort'],
args: 'run dev',
env_file: resolveEnvFile('frontend', instanceNum),
env: {
...loadFrontendEnv(resolveEnvFile('frontend', instanceNum)),
...currentEnvConfig,
// Ensure Vite proxy targets the correct instance backend
VITE_API_URL: `http://localhost:${getInstancePort(3211, instanceNum)}`,
SHIPSEC_INSTANCE: instanceNum,
},
watch: !isProduction ? ['src'] : false,
ignore_watch: ['node_modules', 'dist', '*.log'],
Expand Down