Repository navigation
docs: document serving the kagent UI under a sub-path (#535) - #555
boxcee-interview wants to merge 2 commits into
Conversation
|
CI note: the |
Signed-off-by: Moritz Schmitz von Hülst <mschmitzvonhuelst@gmail.com>
db5ac28 to
a7b56fb
Compare
|
yeah i think the deploy preview doesnt work on forks right now... ill look into that soon |
| author: kagent.dev | ||
| --- | ||
|
|
||
| The kagent UI is served by an nginx sidecar that answers on port `8080` inside the pod. By default it serves at the root (`/`). When a reverse proxy fronts the UI and you want it reachable under a prefix such as `/ui`, set `ui.basePath` in the Helm values. |
There was a problem hiding this comment.
Blocking. nginx is not a sidecar here. ui-deployment.yaml defines a single container named ui, and the Dockerfile's runtime stage is nginx only. nginx is the UI container itself.
| The kagent UI is served by an nginx sidecar that answers on port `8080` inside the pod. By default it serves at the root (`/`). When a reverse proxy fronts the UI and you want it reachable under a prefix such as `/ui`, set `ui.basePath` in the Helm values. | |
| The kagent UI is a static bundle served by nginx, which answers on port `8080` inside the pod. By default it serves at the root (`/`). When a reverse proxy fronts the UI and you want it reachable under a prefix such as `/ui`, set `ui.basePath` in the Helm values. |
| ## The `ui.basePath` value | ||
|
|
||
| | Setting | Default | Effect | | ||
| |---------|---------|--------| | ||
| | `ui.basePath` | `""` (empty) | UI served at `/`. All existing behaviour unchanged. | | ||
| | `ui.basePath` | e.g. `/ui` | UI served under the prefix. One value moves every root-relative URL the UI emits. | | ||
|
|
||
| The value is purely additive: leaving it unset leaves the installation exactly as it is today. |
There was a problem hiding this comment.
Should fix. A table must not open a section: the h2 needs a framing sentence first, and that sentence must add something the table does not. Line 17 already is that sentence, so it mainly needs to move up, with one more line of prose to carry it. I have also dropped "today", which the page outlives.
| ## The `ui.basePath` value | |
| | Setting | Default | Effect | | |
| |---------|---------|--------| | |
| | `ui.basePath` | `""` (empty) | UI served at `/`. All existing behaviour unchanged. | | |
| | `ui.basePath` | e.g. `/ui` | UI served under the prefix. One value moves every root-relative URL the UI emits. | | |
| The value is purely additive: leaving it unset leaves the installation exactly as it is today. | |
| ## The `ui.basePath` value | |
| One Helm value controls the whole sub-path, and it is purely additive: leaving it unset leaves an existing installation serving at the root exactly as before. Set it, and the prefix reaches every URL the UI emits, not only the pages a reader navigates to. | |
| | Setting | Default | Effect | | |
| |---------|---------|--------| | |
| | `ui.basePath` | `""` (empty) | UI served at `/`. All existing behaviour unchanged. | | |
| | `ui.basePath` | e.g. `/ui` | UI served under the prefix. One value moves every root-relative URL the UI emits. | |
|
|
||
| The value is purely additive: leaving it unset leaves the installation exactly as it is today. | ||
|
|
||
| When set, a single value controls the `<base href>` tag, the client-side router basename, and the root-relative API, SSO, userinfo, and share-link URLs that the browser uses. A reader who expects to adjust `publicBackendUrl` by hand should know that the base path already covers it: root-relative URLs such as `publicBackendUrl` inherit the prefix automatically. |
There was a problem hiding this comment.
Should fix. This addresses "a reader" and describes what they ought to know, which reads as scoping notes rather than documentation. State the behavior directly.
| When set, a single value controls the `<base href>` tag, the client-side router basename, and the root-relative API, SSO, userinfo, and share-link URLs that the browser uses. A reader who expects to adjust `publicBackendUrl` by hand should know that the base path already covers it: root-relative URLs such as `publicBackendUrl` inherit the prefix automatically. | |
| When set, a single value controls the `<base href>` tag, the client-side router basename, and the root-relative API, SSO, userinfo, and share-link URLs that the browser uses. `publicBackendUrl` and the other root-relative URLs inherit the prefix, so do not adjust them by hand. |
|
|
||
| When set, a single value controls the `<base href>` tag, the client-side router basename, and the root-relative API, SSO, userinfo, and share-link URLs that the browser uses. A reader who expects to adjust `publicBackendUrl` by hand should know that the base path already covers it: root-relative URLs such as `publicBackendUrl` inherit the prefix automatically. | ||
|
|
||
| ## Proxy shapes |
There was a problem hiding this comment.
Blocking. The page never shows how to set the value. --set ui.basePath=/ui appears only in passing on line 93, so a reader arrives here knowing what the value does but not how to apply it.
Please add a short section before this heading showing the command that sets it. House convention puts a required non-default Helm value on the install step rather than a follow-up helm upgrade, so frame it as installing kagent with the value, and link back to the install page's prerequisites.
|
|
||
| ## Proxy shapes | ||
|
|
||
| Both of the following proxy configurations work. Choose the one that matches your infrastructure. |
There was a problem hiding this comment.
Blocking. True without SSO, but not with it, and the sentence is unqualified.
Tested on v1.0.0-alpha8 with oauth2-proxy.enabled=true: the forwarding shape returns 403 for /ui/login, /ui/health, /ui/env-config.js and /ui/oauth2/start, because --skip-auth-regex and --skip-auth-route are anchored at the root and --proxy-prefix stays /oauth2. The chart's own sign_in.html points at /ui/login, so sign-in loops. values.yaml describes the value the same way: "Prefix a reverse proxy strips before forwarding".
| Both of the following proxy configurations work. Choose the one that matches your infrastructure. | |
| Both of the following proxy configurations work. Choose the one that matches your infrastructure. If you enable oauth2-proxy for SSO, the proxy must strip the prefix: with the prefix forwarded, oauth2-proxy cannot match its own sign-in and skip-authentication paths, and sign-in fails. |
|
|
||
| ## Helm render validation | ||
|
|
||
| Two validations run at Helm render time and fail the install rather than producing a broken UI. Both are defined in `helm/kagent/templates/ui-configmap.yaml`. |
There was a problem hiding this comment.
Should fix. The error an operator actually sees names a different file:
Error: execution error at (kagent/templates/ui-deployment.yaml:21:31): ui.basePath must be a path like /ui
Chart-internal paths also rot — upstream's own init.sh comment already points at the wrong template. Drop the citation.
| Two validations run at Helm render time and fail the install rather than producing a broken UI. Both are defined in `helm/kagent/templates/ui-configmap.yaml`. | |
| Two validations run at Helm render time and fail the install rather than producing a broken UI. |
| 1. Set `OIDC_REDIRECT_URL` to point under the base path (for example `https://example.com/ui/oauth2/start` rather than `https://example.com/oauth2/start`). | ||
| 2. Restart the oauth2-proxy pod after changing the value. |
There was a problem hiding this comment.
Blocking. OIDC_REDIRECT_URL becomes oauth2-proxy's --redirect-url, which is the OAuth callback, not the path that starts sign-in. The chart leaves --proxy-prefix at /oauth2, so the callback is /oauth2/callback.
Tested: /ui/oauth2/start?code=…&state=… returns 302 back to the identity provider, ignoring the code, while /ui/oauth2/callback?code=…&state=… attempts the token exchange. As written, this step produces an endless sign-in loop.
| 1. Set `OIDC_REDIRECT_URL` to point under the base path (for example `https://example.com/ui/oauth2/start` rather than `https://example.com/oauth2/start`). | |
| 2. Restart the oauth2-proxy pod after changing the value. | |
| 1. Set `OIDC_REDIRECT_URL` under `oauth2-proxy.extraEnv` in your Helm values so that it points under the base path, for example `https://example.com/ui/oauth2/callback` rather than `https://example.com/oauth2/callback`. | |
| 2. Register that same URL as a redirect URI with your identity provider. | |
| 3. Restart the oauth2-proxy pod after changing the value. |
| 1. Set `OIDC_REDIRECT_URL` to point under the base path (for example `https://example.com/ui/oauth2/start` rather than `https://example.com/oauth2/start`). | ||
| 2. Restart the oauth2-proxy pod after changing the value. | ||
|
|
||
| The restart is required because the chart's sign-in HTML redirects to `{basePath}/login`, and the oauth2-proxy checksum deliberately renders without the `ui` prefix, so a base-path change alone does not roll the oauth2-proxy pod. Without the restart, the proxy keeps using the old redirect URL and sign-in fails. |
There was a problem hiding this comment.
Should fix. The restart requirement is correct — I verified that changing ui.basePath updates the ConfigMap to url=/console/login while the checksum stays put and the pod does not roll. The reason is a misreading, though: the checksum renders without the ui values key ((.Values.ui | default dict) is empty in that scope), not without the ui URL prefix.
| The restart is required because the chart's sign-in HTML redirects to `{basePath}/login`, and the oauth2-proxy checksum deliberately renders without the `ui` prefix, so a base-path change alone does not roll the oauth2-proxy pod. Without the restart, the proxy keeps using the old redirect URL and sign-in fails. | |
| The restart is required because the chart's sign-in HTML redirects to `{basePath}/login`, but the checksum that would roll the oauth2-proxy pod is computed where the `ui` values key is not in scope. The base path is absent from the hash, so the hash does not change and the pod keeps the old sign-in template and redirect URL until you restart it. |
| After installing with `--set ui.basePath=/ui`: | ||
|
|
||
| 1. Open `/ui/` in a browser. The UI should load. | ||
| 2. Navigate to an agent list or detail page. The URL should stay under `/ui/...` (for example `/ui/agents`). | ||
| 3. Open the browser network tab. API calls should go to `/ui/api/...`, not `/api/...`. | ||
| 4. Reload the page. The SPA router should keep the prefix. | ||
| 5. If oauth2-proxy is enabled, sign in. The redirect should land under `/ui/oauth2/...`. |
There was a problem hiding this comment.
Should fix. These are "should" statements rather than steps with expected results, and the rejection path issue #535 asked to be recorded is missing.
Give each check an explicit expected result, and add a step that sets a rejected value such as /api and shows what Helm prints:
Error: execution error at (kagent/templates/ui-deployment.yaml:21:31): ui.basePath cannot start with a path nginx serves, such as /api or /assets
Step 5 also needs the caveat from the "Proxy shapes" thread: the redirect lands under /ui/oauth2/... only when the proxy strips the prefix.
There was a problem hiding this comment.
Optional, take or leave. Every other 1.x page closes with a Next steps cards block. The install page and the identity page would be the obvious cards here.
Signed-off-by: Moritz Schmitz von Hülst <mschmitzvonhuelst@gmail.com>
Closes #535
The 1.x doc set has no coverage for ui.basePath (added in kagent#2904, shipped in v1.0.0-alpha3). This adds a dedicated setup page, as the issue asks.
The new page covers:
installation.md gets a link to the new page at the point where a reader meets the UI service.
How to Test
Hugo 0.160.1 extended build of docs-site (hugo --config hugo.yaml --gc --minify) succeeds, and both the new page (docs-site/public/kagent/1.x/setup/reverse-proxy/) and the installation.md link to it resolve to a real output file.