Skip to content

build(ui): serve the UI from distroless nginx with a Go entrypoint - #3316

Merged
EItanya merged 5 commits into
mainfrom
charlesthebird/distrolessUi
Oct 22, 2026
Merged

EItanya merged 5 commits into
mainfrom
charlesthebird/distrolessUi

Conversation

@Charlesthebird

@Charlesthebird Charlesthebird commented Oct 21, 2026 •

Copy link
Copy Markdown
Collaborator

🤖 written by Claude (start)

Changes

The UI image's runtime stage is now chainguard/nginx, with no shell or curl. A static Go entrypoint replaces init.sh and keeps its contract: same env vars, defaults, validation, output files and nginx arguments.

Piece Where
Entrypoint: makes the /tmp dirs, renders env-config.js, sets <base href>, execs nginx main.go:23
Test that runs the old init.sh beside it and diffs the files and warnings main_test.go:14
Go builder stage and distroless runtime stage Dockerfile:61
Base images pinned by digest Dockerfile:3

The chart is unchanged apart from the probe docs: exec probes can't run without a shell, so use httpGet or tcpSocket. ui/.nvmrc is 24.22.1. The image drops from 56MB to 28MB, and trivy and grype report 0 findings (1 and 2 before).

Reviewer notes

  • Warnings start with entrypoint: instead of init.sh:.
  • The old script lives in ui/entrypoint/testdata as the test's reference.

Testing

  1. docker build -t kagent-ui:dev -f ui/Dockerfile ui, then kind load docker-image kagent-ui:dev.
  2. Install with that image, --set ui.basePath=/ui, and a ui.env entry for KAGENT_UI_EXTENSION_TOKEN that reads a Secret via valueFrom.
  3. Port-forward the UI; curl localhost:8080/ui/env-config.js shows the Secret's value and "BASE_PATH": "/ui".
  4. curl localhost:8080/ui/agents shows <base href="/p/https://github.com/ui/", and the pod passes its /health probe.

Release note

The UI image now runs on a distroless nginx base with no shell; UI settings work as before, and custom exec probes must use httpGet or tcpSocket.


🤖 written by Claude (end)

🤖 Generated with Claude Code

Nicholas Bucher and others added 2 commits October 21, 2026 17:22
The runtime stage is cgr.dev/chainguard/nginx with no shell. The chart now
renders env-config.js into the ui-config ConfigMap and rewrites <base href>
with sub_filter, replacing init.sh and the ui ConfigMap env.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Nicholas Bucher <nicholas.bucher@solo.io>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Nicholas Bucher <nicholas.bucher@solo.io>
Charlesthebird

This comment was marked as resolved.

…nd init.sh references

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Signed-off-by: Nicholas Bucher <behappy54321@gmail.com>
Charlesthebird

This comment was marked as resolved.

@Charlesthebird

This comment has been minimized.

Charlesthebird

This comment was marked as resolved.

@Charlesthebird

This comment has been minimized.

@Charlesthebird
Charlesthebird marked this pull request as ready for review October 22, 2026 17:35
@Charlesthebird
Charlesthebird requested a review from a team as a code owner October 22, 2026 17:35
…tays distroless

The entrypoint replaces init.sh with the same env vars, defaults, validation and
output files, then execs nginx. The chart's env flow is unchanged from main.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Signed-off-by: Nicholas Bucher <behappy54321@gmail.com>
@Charlesthebird Charlesthebird changed the title build(ui): serve the UI from distroless nginx build(ui): serve the UI from distroless nginx with a Go entrypoint Oct 22, 2026
…ript

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Signed-off-by: Nicholas Bucher <behappy54321@gmail.com>
Charlesthebird

This comment was marked as resolved.

@Charlesthebird

Charlesthebird commented Oct 22, 2026 •

Copy link
Copy Markdown
Collaborator Author

Both UI images ran on one kind cluster installed with make build kagent-cli-deploy, with real data: agents assistant and k8s-helper (both Ready), models default-model-config and gpt-4o-model-config. Only the UI image changed between runs: main at 0e1bd46 vs this PR at 4e8635c.

  • Agents page: both list the 2 agents.
  • Models page: both list the 2 model configs.
  • Agent details: k8s-helper shows its model, description and prompt on both.
  • Deep-link reload: /agents/kagent/k8s-helper/edit renders after a reload on both.
  • /env-config.js: identical on both. Timeout 90000 comes from the chart ConfigMap, KAGENT_UI_EXTENSION_DEMO_TOKEN from a Secret via ui.env.
  • ui.basePath=/ui: both serve agents and models under /ui and survive a nested reload.
  • Pod and logs: UI pod is 1/1 Ready on both. The new image has no shell, so the clip uses kubectl logs and curl.

🤖 written by Claude

kagent-pr3316-verify.mp4

Screenshots

Before: Agents page before-agents-list
After: Agents page after-agents-list
Before: Models page before-models-list
After: Models page after-models-list
Before: agent details before-agent-details
After: agent details after-agent-details
Before: /env-config.js before-env-config
After: /env-config.js after-env-config
Before: Agents under /ui before-base-path-agents
After: Agents under /ui after-base-path-agents
Before: reload under /ui before-base-path-deep-link
After: reload under /ui after-base-path-deep-link

🤖 written by Claude

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.

2 participants

⌂ 换网址