feat(homepage): smooth load + single-pane-of-glass for all UI apps#1608
Merged
Conversation
Eliminates the cold-load flicker and surfaces every UI-bearing app on the
dashboard, so the homepage is genuinely the one entry point for every
hosted service.
## Flicker — two root causes
1. **Remote Unsplash background image** (~2000px wide) applied via inline
style after React hydration. Browser painted default white before the
image — and before the slate theme color — applied, producing a
visible flash on every cold load and after each oauth2-proxy redirect.
2. **replicaCount=2 with default ClusterIP, no session affinity.** The
Kubernetes widget polls cluster/node CPU+memory every few seconds;
round-robin between two pods (each with its own kube-apiserver watcher
cache) made values pop between slightly-stale and slightly-fresh on
every refresh.
## Fix
- Drop `background.image`, `background.blur`, `background.opacity`, and
`cardBlur` entirely. Replace with a soft two-point radial mesh
gradient in `custom.css` (slate-950 base, subtle blue + violet auras,
`background-attachment: fixed`). Zero remote assets — flicker is now
structurally impossible.
- Lean into Homepage's own modern UI options: `headerStyle: clean`,
`statusStyle: dot`, `iconStyle: gradient`, `hideVersion: true`,
`target: _blank`.
- Pin the homepage Service to `sessionAffinity: ClientIP` via a
post-renderer patch so each oauth2-proxy backend sticks to one
homepage replica and the widget reads from a consistent cache.
## Coverage
Every UI-bearing HTTPRoute now carries `gethomepage.dev/*` annotations
so auto-discovery picks them up:
| App | Group | Source of annotations |
|--------------------|-----------------|-------------------------------------|
| actual-budget | Finance | base (existing) |
| whoami | Diagnostics | base — added `href`+`pod-selector` |
| fleetdm | Device Mgmt | base (existing) |
| headlamp | Kubernetes | base — added `href`+`pod-selector` |
| openbao (Vault) | Security | base (existing) |
| flux-operator | Kubernetes | base (existing) |
| hubble-ui | Diagnostics | base (existing) |
| wedding-app | Personal Sites | hetzner Flux Kustomization patch |
| ascoachingogvaner | Customer Sites | hetzner Flux Kustomization patch |
wedding-app and ascoachingogvaner ship their HTTPRoute from external OCI
artifacts (`oci://ghcr.io/devantler-tech/{wedding-app,ascoachingogvaner}/
manifests`), so the annotations are injected via the existing Flux
Kustomization `spec.patches` — the same place that already rewrites
their hostnames. Strategic-merge patch (not JSON-Patch `op: add
/metadata/annotations`) so we merge into — rather than overwrite — any
annotations on the upstream HTTPRoute.
The `layout:` in settings.yaml now lists the previously-unmapped groups
(`Security`, `Finance`, `Personal Sites`, `Customer Sites`) with
intentional icons and a deliberate render order.
Correctly excluded from auto-discovery: the HTTP→HTTPS redirect route,
homepage's own route, oauth2-proxy, and dex (OIDC IdP — only visited as
a login redirect).
## Cleanup
- Removed the stale `goldilocks.platform.lan` line from `hosts` — no
Goldilocks resources exist anywhere in the repo.
Validated with `ksail workload validate` against both `ksail.yaml` and
`ksail.prod.yaml` (254/254 each).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR improves the Homepage dashboard experience by removing cold-load flicker sources (remote background + inconsistent widget polling across replicas) and ensuring all UI-bearing apps are discoverable and grouped consistently via gethomepage.dev/* annotations.
Changes:
- Removes the remote
background.imageconfiguration and replaces it with a local CSS radial-mesh gradient backdrop. - Adds/extends
gethomepage.dev/*discovery annotations (includinghrefandpod-selector) so more UI apps appear correctly on the Homepage dashboard. - Pins the Homepage Service with
sessionAffinity: ClientIPvia Helm post-render patching to stabilize Kubernetes widget polling across multiple replicas.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| k8s/providers/hetzner/apps/wedding-app/patches/kustomization-patch.yaml | Injects Homepage discovery annotations onto the upstream (OCI-sourced) HTTPRoute via strategic-merge patch. |
| k8s/providers/hetzner/apps/ascoachingogvaner/patches/kustomization-patch.yaml | Injects Homepage discovery annotations onto the upstream (OCI-sourced) HTTPRoute via strategic-merge patch. |
| k8s/bases/apps/whoami/httproute.yaml | Adds href + pod-selector annotations to improve Homepage auto-discovery and widget targeting. |
| k8s/bases/apps/homepage/helm-release.yaml | Adds a post-render JSON6902 patch to enable sessionAffinity: ClientIP on the Homepage Service. |
| k8s/bases/apps/homepage/config-map.yaml | Updates Homepage settings (layout/groups/UI style) and replaces the remote background image with local custom.css gradient. |
| k8s/bases/apps/headlamp/httproute.yaml | Adds href + pod-selector annotations to improve Homepage auto-discovery and widget targeting. |
| hosts | Removes stale goldilocks.platform.lan entry. |
Contributor
|
🎉 This PR is included in version 1.12.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Eliminates the cold-load flicker and surfaces every UI-bearing app on the dashboard, so the homepage is genuinely the one entry point for every hosted service.
Flicker — two root causes
replicaCount=2with default ClusterIP, no session affinity. The Kubernetes widget polls cluster/node CPU+memory every few seconds; round-robin between two pods (each with its own kube-apiserver watcher cache) made values pop between slightly-stale and slightly-fresh on every refresh.Fix
background.image,background.blur,background.opacity, andcardBlurentirely. Replace with a soft two-point radial mesh gradient incustom.css(slate-950 base, subtle blue + violet auras,background-attachment: fixed). Zero remote assets — flicker is now structurally impossible.headerStyle: clean,statusStyle: dot,iconStyle: gradient,hideVersion: true,target: _blank.sessionAffinity: ClientIPvia a post-renderer patch so each oauth2-proxy backend sticks to one homepage replica and the widget reads from a consistent cache.Coverage
Every UI-bearing HTTPRoute now carries
gethomepage.dev/*annotations so auto-discovery picks them up:href+pod-selectorhref+pod-selectorwedding-appandascoachingogvanership their HTTPRoute from external OCI artifacts (oci://ghcr.io/devantler-tech/{wedding-app,ascoachingogvaner}/manifests), so the annotations are injected via the existing Flux Kustomizationspec.patches— the same place that already rewrites their hostnames. Strategic-merge patch (not JSON-Patchop: add /metadata/annotations) so we merge into — rather than overwrite — any annotations on the upstream HTTPRoute.The
layout:insettings.yamlnow lists the previously-unmapped groups (Security,Finance,Personal Sites,Customer Sites) with intentional icons and a deliberate render order.Correctly excluded from auto-discovery: the HTTP→HTTPS redirect route, homepage's own route, oauth2-proxy, and dex (OIDC IdP — only visited as a login redirect).
Cleanup
goldilocks.platform.lanline fromhosts— no Goldilocks resources exist anywhere in the repo.Validation
🤖 Generated with Claude Code