feat(deploy): single-origin path-based deployment + project site
Serve the whole stack behind one host: site at /, game UI at /game/, gateway REST at /api + /healthz, Connect at /rpc (prefix stripped by the edge Caddy). The built artifact is domain-agnostic — the UI talks to the gateway same-origin via relative URLs, so the same bundle runs under any host with no rebuild and with CORS disabled. - Rename the Connect proto service galaxy.gateway.v1.EdgeGateway -> edge.v1.Gateway; regenerate Go + TS; public path /rpc/edge.v1.Gateway. - Move the game UI under base path /game (env BASE_PATH); make the manifest, service-worker scope, WASM loader, and all navigation base-aware via a withBase helper. - Relative API + /rpc Connect prefix; Vite dev proxy mirrors the strip. - Rewrite the edge Caddy (dev + prod) for path-based routing; empty CORS allow-lists (same-origin); single host. - New VitePress project site (site/): i18n en/ru with switcher, LaTeX math, minimal monospace theme; built and served at /. - dev-deploy compose/Makefile + CI (dev-deploy, prod-build, new site-build) build and seed the site; probes hit /, /game/, /healthz. - Sync docs (ARCHITECTURE, gateway README/openapi, dev-deploy & local-dev READMEs, CLAUDE.md, ui/PLAN). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -14,8 +14,8 @@ This stack is **not** a CI gate (the per-stage CI gate now lives on
|
||||
`gitea.lan`; see project-level `CLAUDE.md`). It is also distinct from
|
||||
the **long-lived dev environment** at
|
||||
[`tools/dev-deploy/`](../dev-deploy/README.md), which is redeployed on
|
||||
every merge into `development` and is reachable as
|
||||
`https://www.galaxy.lan` / `https://api.galaxy.lan`. The two stacks
|
||||
every merge into `development` and is reachable at the single origin
|
||||
`https://galaxy.lan` (site at `/`, game UI at `/game/`). The two stacks
|
||||
(`tools/local-dev/` and `tools/dev-deploy/`) coexist on the same host
|
||||
because every name — compose project, container, network, volume — is
|
||||
distinct.
|
||||
@@ -131,7 +131,7 @@ host compose network "galaxy-local-de
|
||||
┌────────────────────────────────┐ ┌──────────────────────────────┐
|
||||
│ browser localhost:5173 │── pnpm dev (Vite, host) ──┐ │
|
||||
│ ↳ /api/* proxied ───┼──────────────────────────▶│ gateway:8080 │
|
||||
│ ↳ /galaxy.gateway... ┼──────────────────────────▶│ │
|
||||
│ ↳ /rpc/* proxied ───┼──────────────────────────▶│ gateway:9090 │
|
||||
│ browser localhost:8025 │─────────────────────────▶│ mailpit:8025 │
|
||||
│ psql localhost:5433 │─────────────────────────▶│ postgres:5432 │
|
||||
│ redis-cli localhost:6380 │─────────────────────────▶│ redis:6379 │
|
||||
@@ -141,8 +141,9 @@ host compose network "galaxy-local-de
|
||||
└────────────────────────────────┘
|
||||
```
|
||||
|
||||
Vite's dev server proxies `/api` and `/galaxy.gateway.v1.EdgeGateway`
|
||||
to the gateway, so every browser request stays same-origin (no CORS
|
||||
Vite's dev server proxies `/api` (to the gateway REST listener) and
|
||||
`/rpc` (to the authenticated Connect/gRPC-Web listener, stripping the
|
||||
`/rpc` prefix), so every browser request stays same-origin (no CORS
|
||||
preflight). The gateway is therefore reachable only through Vite at
|
||||
<http://localhost:5173>, not at <http://localhost:8080> from the
|
||||
browser tab. Direct curl/wget against <http://localhost:8080> still
|
||||
@@ -291,9 +292,9 @@ make status docker compose ps
|
||||
## Relationship to other infrastructure
|
||||
|
||||
- `tools/dev-deploy/` — long-lived dev environment redeployed on every
|
||||
merge into `development`; reachable at `https://www.galaxy.lan` /
|
||||
`https://api.galaxy.lan`. Distinct compose project, container names,
|
||||
network and volumes.
|
||||
merge into `development`; reachable at the single origin
|
||||
`https://galaxy.lan` (site at `/`, game UI at `/game/`). Distinct
|
||||
compose project, container names, network and volumes.
|
||||
- `integration/testenv/` — testcontainers harness used by
|
||||
`make -C integration integration`. Uses the canonical
|
||||
`backend/Dockerfile` / `gateway/Dockerfile` at production defaults;
|
||||
|
||||
@@ -180,7 +180,7 @@ services:
|
||||
GATEWAY_PUBLIC_HTTP_ANTI_ABUSE_SEND_EMAIL_CODE_IDENTITY_RATE_LIMIT_BURST: "1000"
|
||||
GATEWAY_PUBLIC_HTTP_ANTI_ABUSE_CONFIRM_EMAIL_CODE_IDENTITY_RATE_LIMIT_REQUESTS: "10000"
|
||||
GATEWAY_PUBLIC_HTTP_ANTI_ABUSE_CONFIRM_EMAIL_CODE_IDENTITY_RATE_LIMIT_BURST: "1000"
|
||||
# public_misc class wraps the authenticated EdgeGateway gRPC
|
||||
# public_misc class wraps the authenticated edge.v1.Gateway gRPC
|
||||
# endpoints (ExecuteCommand, SubscribeEvents). The gateway's
|
||||
# default for this class is 0 bytes, which rejects every
|
||||
# non-empty body with HTTP 413; override with a generous limit
|
||||
@@ -200,7 +200,7 @@ services:
|
||||
GATEWAY_AUTHENTICATED_GRPC_ANTI_ABUSE_MESSAGE_CLASS_RATE_LIMIT_BURST: "1000"
|
||||
ports:
|
||||
- "${LOCAL_DEV_GATEWAY_REST_PORT:-8080}:8080"
|
||||
# Authenticated EdgeGateway connect-web/gRPC listener. The
|
||||
# Authenticated edge.v1.Gateway connect-web/gRPC listener. The
|
||||
# browser reaches it via the Vite dev proxy in
|
||||
# ui/frontend/vite.config.ts.
|
||||
- "${LOCAL_DEV_GATEWAY_GRPC_PORT:-9090}:9090"
|
||||
|
||||
Reference in New Issue
Block a user