138 lines
4.9 KiB
Markdown
138 lines
4.9 KiB
Markdown
# Port allocation
|
|
|
|
Canonical port plan for both stacks (tenant + SuperAdmin). Every port is
|
|
env-configurable; defaults below are non-colliding so both stacks can run
|
|
simultaneously on a single workstation.
|
|
|
|
## Dev ports
|
|
|
|
| Port | Service | Stack | Default env var | Config file |
|
|
|------|---------------------|------------|--------------------------|------------------------------------------|
|
|
| 3000 | Tenant client (Vite) | tenant | `VITE_PORT` | `client/vite.config.ts` |
|
|
| 3001 | Tenant API (Express) | tenant | `PORT` | `server/src/config/index.js` |
|
|
| 3002 | SuperAdmin API (Express) | superadmin | `SUPERADMIN_PORT` | `superadmin/server/src/index.js` |
|
|
| 3003 | SuperAdmin client (Vite) | superadmin | `VITE_PORT` (client) | `superadmin/client/vite.config.ts` |
|
|
|
|
The four dev ports (3000, 3001, 3002, 3003) are non-colliding by default.
|
|
|
|
Vite dev servers run with `strictPort: true`. If a port is already in use,
|
|
they fail fast rather than silently picking a different port — so a
|
|
collision is loud, not silent.
|
|
|
|
## Cross-stack proxy targets
|
|
|
|
| From / stack | To / stack | Default | Override env var |
|
|
|------------------------|-------------------------------|------------------------------------|----------------------|
|
|
| Tenant client `/api` | Tenant API | `http://127.0.0.1:3001` | `VITE_API_TARGET` |
|
|
| Tenant client `/uploads` | Tenant API | `http://127.0.0.1:3001` | `VITE_API_TARGET` |
|
|
| Tenant client `/ws`, `/socket` | Tenant API (WS) | `ws://127.0.0.1:3001` | `VITE_WS_TARGET` |
|
|
| SuperAdmin client `/api` | SuperAdmin API | `http://localhost:3002` | `SUPERADMIN_PORT` + `SUPERADMIN_SERVER_HOST` |
|
|
| Tenant client license JWKS | SuperAdmin API | `/api/v1/auth/jwks` (relative; defaults via Vite proxy are NOT used) | `VITE_SUPERADMIN_JWKS_URL` |
|
|
|
|
The JWKS endpoint is only exposed by the SuperAdmin server. The tenant
|
|
client must point at the SuperAdmin origin explicitly — set
|
|
`VITE_SUPERADMIN_JWKS_URL` to a full URL such as
|
|
`http://localhost:3002/api/v1/auth/jwks` (or any reverse-proxied path)
|
|
when both stacks are running. If the URL is relative (starts with `/`)
|
|
the tenant axios instance is used; if it is absolute (`http://` / `https://`)
|
|
a one-off `fetch()` is used instead so cross-origin requests work.
|
|
|
|
## Running both stacks simultaneously
|
|
|
|
The default ports are chosen so the two stacks do not collide. Open four
|
|
terminals (or use a terminal multiplexer):
|
|
|
|
```bash
|
|
# Terminal 1 — tenant API on :3001
|
|
cd server
|
|
npm run dev
|
|
|
|
# Terminal 2 — tenant client on :3000 (proxies /api → :3001)
|
|
cd client
|
|
npm run dev
|
|
|
|
# Terminal 3 — SuperAdmin API on :3002
|
|
cd superadmin/server
|
|
npm run dev
|
|
|
|
# Terminal 4 — SuperAdmin client on :3003 (proxies /api → :3002)
|
|
cd superadmin/client
|
|
npm run dev
|
|
```
|
|
|
|
You can also run any one stack in isolation — the defaults match the
|
|
one-stack commands documented in `AGENTS.md`.
|
|
|
|
## Changing ports
|
|
|
|
Each port is overridable via an env var. Set the env var before the
|
|
`npm run dev` (or `npm start`) command, or persist it in a `.env` file
|
|
(see the per-stack `.env.example`).
|
|
|
|
### Tenant API
|
|
|
|
```bash
|
|
# server/.env
|
|
PORT=3101
|
|
```
|
|
|
|
Then start with `cd server && npm run dev`. The client must be told
|
|
where the API lives:
|
|
|
|
```bash
|
|
# client/.env (or inline)
|
|
VITE_API_TARGET=http://127.0.0.1:3101
|
|
VITE_WS_TARGET=ws://127.0.0.1:3101
|
|
VITE_PORT=3100
|
|
```
|
|
|
|
### Tenant client (Vite)
|
|
|
|
```bash
|
|
# client/.env
|
|
VITE_PORT=3100 # Vite dev port
|
|
VITE_API_TARGET=http://127.0.0.1:3101
|
|
VITE_WS_TARGET=ws://127.0.0.1:3101
|
|
```
|
|
|
|
### SuperAdmin API
|
|
|
|
```bash
|
|
# superadmin/server/.env
|
|
SUPERADMIN_PORT=3202
|
|
```
|
|
|
|
### SuperAdmin client (Vite)
|
|
|
|
```bash
|
|
# superadmin/client/.env
|
|
VITE_PORT=3203 # Vite dev port
|
|
SUPERADMIN_PORT=3202 # must match the SuperAdmin API
|
|
SUPERADMIN_SERVER_HOST=http://localhost
|
|
```
|
|
|
|
### Tenant → SuperAdmin JWKS
|
|
|
|
```bash
|
|
# client/.env — relative path (tenant axios instance)
|
|
VITE_SUPERADMIN_JWKS_URL=/api/v1/auth/jwks
|
|
|
|
# client/.env — absolute cross-origin (one-off fetch())
|
|
VITE_SUPERADMIN_JWKS_URL=http://localhost:3002/api/v1/auth/jwks
|
|
```
|
|
|
|
In production, point this at a reverse-proxied origin that fronts the
|
|
SuperAdmin API (e.g. `https://superadmin.example.com/api/v1/auth/jwks`).
|
|
|
|
## Collision detection
|
|
|
|
Both Vite configs use `strictPort: true`. If a port is already bound,
|
|
the dev server exits with a clear error instead of silently picking a
|
|
different port — so a collision is loud, not hidden. Both Express
|
|
servers bind to the configured `PORT` / `SUPERADMIN_PORT`; if the
|
|
port is unavailable, Node throws `EADDRINUSE` at startup.
|
|
|
|
Default values give every service a unique port, so merely changing
|
|
nothing is the recommended setup. Override only when you need to
|
|
work around a port already in use on the host.
|