ShipSec Studio supports running multiple isolated dev instances (0-9) on one machine.
# Instance 0 (default) — works exactly as before
just dev
# Instance 1 — runs on offset ports (frontend :5273, backend :3311)
SHIPSEC_INSTANCE=1 just dev
# Or persist the choice for this workspace
echo 1 > .shipsec-instance
just dev # now uses instance 1
# Stop your instance
SHIPSEC_INSTANCE=1 just dev stop- One shared Docker infra stack: Postgres, Temporal, Redpanda, Redis, MinIO, etc.
- Many app instances via PM2:
shipsec-{backend,worker,frontend}-N - Isolation via namespacing, not per-instance containers:
- Postgres database:
shipsec_instance_N - Temporal namespace + task queue:
shipsec-dev-N - Kafka client/group IDs:
shipsec-*-N
- Postgres database:
The instance is resolved in this order:
SHIPSEC_INSTANCEenvironment variable (highest priority).shipsec-instancefile in repo root (gitignored)- Defaults to
0
# Per-command
SHIPSEC_INSTANCE=2 just dev
# Per-workspace (persistent)
echo 2 > .shipsec-instancePorts are offset by N * 100:
| Service | Base | Instance 0 | Instance 1 | Instance 2 | Instance 5 |
|---|---|---|---|---|---|
| Frontend | 5173 | 5173 | 5273 | 5373 | 5673 |
| Backend | 3211 | 3211 | 3311 | 3411 | 3711 |
Shared infra (fixed ports, same for all instances):
| Service | Port |
|---|---|
| Postgres | 5433 |
| Temporal | 7233 |
| Temporal UI | 8081 |
| Redis | 6379 |
| Redpanda (Kafka) | 19092 |
| Redpanda Console | 8082 |
| MinIO API/UI | 9000 / 9001 |
| Loki | 3100 |
The nginx reverse proxy (http://localhost) always routes to instance 0 (ports 5173/3211 are hardcoded in docker/nginx/nginx.dev.conf). This is by design — nginx is shared infra.
For non-zero instances, access your app directly:
# Instance 1
http://localhost:5273 # frontend
http://localhost:3311/api # backend API
The Vite dev server proxies /api calls to the correct backend port automatically (computed from SHIPSEC_INSTANCE in vite.config.ts).
All commands respect SHIPSEC_INSTANCE:
# Start
SHIPSEC_INSTANCE=1 just dev
# Stop (only stops PM2 apps; infra stays running for other instances)
SHIPSEC_INSTANCE=1 just dev stop
# Logs (filtered to your instance's PM2 apps)
SHIPSEC_INSTANCE=1 just dev logs
# Status
SHIPSEC_INSTANCE=1 just dev status
# Clean (stops PM2 apps; only tears down infra if instance 0)
SHIPSEC_INSTANCE=1 just dev cleanWhen stopping/cleaning instance 0, Docker infra is also torn down. For non-zero instances, only the PM2 apps are stopped (since other instances may still need the shared infra).
E2E tests use the same instance resolution to pick the right backend port:
# Against the active instance
bun run test:e2e
# Against a specific instance
SHIPSEC_INSTANCE=2 bun run test:e2e# Check which process is using the port
lsof -i :5273 # frontend instance 1
lsof -i :3311 # backend instance 1SHIPSEC_INSTANCE=1 just dev logs
SHIPSEC_INSTANCE=1 just dev stop
SHIPSEC_INSTANCE=1 just devjust dev stop # stops instance 0 + infra
just infra clean