Skip to content

feat(gateway): serve the monitoring UIs from sub-paths of the single gateway port (#93) - #169

Merged
davidamacey merged 7 commits into
mainfrom
feat/gateway-subpaths
Oct 9, 2026
Merged

davidamacey merged 7 commits into
mainfrom
feat/gateway-subpaths

Conversation

@davidamacey

Copy link
Copy Markdown
Owner

Closes #93.

OP_GATEWAY_SUBPATHS (default false) makes the Cropwright nginx the one published port: /grafana/, /prometheus/, /dashboards/ and /mlflow/ are proxied (Grafana Live websocket included) while the UIs stay on loopback; /docs, /redoc, /openapi.json and /docs-assets/ stay at the root. The API serves path-relative resource_links in gateway mode (explicit OP_*_URL still wins; host:port derivation unchanged when off), and the MLflow run link follows.

Design notes: no new compose profile, the cropwright service is the gateway. A shared entrypoint wrapper (x-gateway-wrap) sets each UI's sub-path settings only when the switch is on and is a plain exec otherwise. Deviation from the issue: MLflow is NOT started with --static-prefix, because that moves /health and /api and breaks the in-network tracking URI, healthcheck and reachability probe; nginx strips /mlflow/ and sends Host: $proxy_host so MLflow 3's allowed-hosts guard passes. Fail closed: with the switch on, the UIs refuse to start when published beyond loopback, and Grafana refuses the default or empty admin password. Also: absolute_redirect off, and 404 for the four sub-paths when the switch is off (found live: they served the SPA shell).

Verified live in an isolated stack (127.0.0.1 only, no GPU): every link renders through the gateway port, Grafana websocket 101, MLflow 200 not 403, Prometheus query UI, Dashboards home; gateway OFF (the default) starts all four UIs through the wrapper and serves them on their own ports; both refusal paths exit 1; teardown proven. Frontend: check 0 errors, lint, 4391 vitest, build, 238 e2e. Backend: full suite 7094 passed, contracts in sync, pre-commit all hooks.

Not done: an installer/CLI flag (set OP_GATEWAY_SUBPATHS=true in .env); Grafana's session cookie has no Secure flag behind TLS (GF_SECURITY_COOKIE_SECURE=true would address it); the X-Forwarded-Proto reaching each upstream was checked in nginx config tests only.

@davidamacey
davidamacey merged commit e128e22 into main Oct 9, 2026
10 checks passed
@davidamacey
davidamacey deleted the feat/gateway-subpaths branch October 9, 2026 23:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: gateway sub-path routing for the monitoring UIs (single port, UIs stay on localhost)

1 participant