feat(cloud-api): bake cloud-console SPA into the image and serve at /console
Multi-stage Dockerfile: stage 1 (node:20-bookworm-slim) builds cloud-console with vite base "/console/"; stage 2 (uv) copies dist/ to /app/console-static. Cloud API mounts the SPA at /console via SpaStaticFiles (StaticFiles subclass that falls back to index.html for deep-link refreshes) when the new CLOUD_CONSOLE_STATIC_DIR env is set, and 307-redirects / to /console/. Static files bypass bearer auth (the SPA shell is public; tokens are still required for /v1/*). Compose enables the mount by default; local dev still uses npm run dev + CLOUD_CONSOLE_CORS_ORIGINS. Jenkinsfile passes mirror overrides (NODE_IMAGE, NPM_REGISTRY, UV_IMAGE, APT_MIRROR, UV_INDEX_URL) as --build-arg, defaulting to CN mirrors (registry.jerryyan.net, registry.npmmirror.com, registry-ghcr.jerryyan.top, mirrors.aliyun.com) so CN builds don't time out; Dockerfile ARGs default to official upstreams so `docker build .` still works anywhere. Backend suite: 443 passed (-m "not integration"); cloud-console typecheck and production build succeed with the new base path. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -251,6 +251,30 @@ For a production build, run `npm run build` and serve the resulting `dist/`
|
||||
behind any static file server or CDN, with `VITE_CLOUD_API_BASE_URL` baked in
|
||||
at build time. The deployed origin must be in `CLOUD_CONSOLE_CORS_ORIGINS`.
|
||||
|
||||
### Same-origin deployment (baked into the Cloud API image)
|
||||
|
||||
The Jenkins-built Docker image already carries the SPA at `/app/console-static`,
|
||||
and `compose.yaml` / `compose.deploy.yaml` set
|
||||
`CLOUD_CONSOLE_STATIC_DIR=/app/console-static` on the `cloud-api` service. In
|
||||
this mode the Cloud API itself serves the console at `/console/` (visiting `/`
|
||||
307-redirects there), so operators can open `https://<cloud-api-host>:8001/`
|
||||
directly — no separate dev server, no static host, no CORS allow-list needed
|
||||
(the SPA and the API share one origin).
|
||||
|
||||
The SPA shell (`index.html`, JS, CSS) is served without a bearer token by
|
||||
design — `_authorize(...)` is called inside the `/v1/*` route handlers, not in
|
||||
middleware, so the SPA can boot before the operator pastes a token. All
|
||||
`/v1/*` API calls still require `tasks:read`/`pool:read`/`plugins:read` scopes
|
||||
as before.
|
||||
|
||||
To opt out (e.g. for local development where you run `npm run dev`), leave
|
||||
`CLOUD_CONSOLE_STATIC_DIR` unset. The mount is conditional on that env var.
|
||||
|
||||
Jenkins build args (`NODE_IMAGE`, `NPM_REGISTRY`, `UV_IMAGE`, `APT_MIRROR`,
|
||||
`UV_INDEX_URL`) default to CN mirrors so builds don't time out pulling from
|
||||
Docker Hub / ghcr.io / npmjs.org / deb.debian.org. Blank any of them to fall
|
||||
back to the upstream.
|
||||
|
||||
## Runtime AI Planner
|
||||
|
||||
The Host Agent reuses the local Runtime planner. AI planning is disabled by
|
||||
|
||||
Reference in New Issue
Block a user