TazLab K8s Homepage Dashboard

Level 2 (Topic) — the gethomepage service dashboard: app architecture, the 2026-08 outage and its fixes, and its Flux image automation pipeline.

Scope

Homepage is the TazLab service dashboard. It runs in cluster mode with Kubernetes RBAC, exposes itself only over the Tailscale ingress, and its image is managed by Flux image automation (pipeline #4).

Architecture

Manifests live in infrastructure/instances/homepage/ (deployed by the infrastructure-instances Kustomization):

FileContents
homepage.yamlNamespace, ServiceAccount, ClusterRole + ClusterRoleBinding (services, pods, nodes, namespaces, ingresses, metrics), ConfigMap homepage-config, Deployment, Service
tailnet-ingress.yamlTailscale IngressClass ingress, host home → home.magellanic-gondola.ts.net, backend port 8000, tagged tag:internal-apps

Key facts:

  • Image: ghcr.io/gethomepage/homepage — currently v2.2.0 (automation-bumped; see below), pin floor v2.1.2.
  • Cluster mode: ConfigMap homepage-config sets kubernetes.yaml: mode: cluster, Traefik discovery, settings.yaml (title “TazLab Dashboard”, custom logo from the repo).
  • RBAC: read-only watch over services/pods/nodes/namespaces/ingresses/metrics — no writes.
  • Service: ClusterIP, port 8000 → container port 3000.
  • Env: HOMEPAGE_ALLOWED_HOSTS: "home.magellanic-gondola.ts.net,home.tazlab.net" — required so the app’s auth gate accepts the hostnames used by probes and ingress.

The 2026-08-24 → 28 Outage

  1. Trigger: a power loss restarted the cluster. The homepage image had been unpinned (:latest), so the pull came back with v2.0.0 instead of the previous working version.
  2. Failure mode: v2.0.0’s auth gate rejected the kubelet’s HTTP probes — the probe requests arrived without a matching allowed Host, and the app answered 400. Liveness failed → restart → fail again. Result: 1210+ restarts while the pod could never become Ready.
  3. Fixes (commit 00a2b99, 2026-08-28):
    • Pin the image to v2.1.2.
    • Add explicit Host: home.magellanic-gondola.ts.net header to both liveness and readiness probes.
    • Set HOMEPAGE_ALLOWED_HOSTS to include the tailnet hostname.
    • Switch exposure to the Tailscale ingress (tailnet-ingress.yaml).

Related hardening from the same window: cloudflare-ddns image pinned to favonia/cloudflare-ddns:1.17.0 and its ExternalSecret removed (secret delivered via VSO). See Secrets Mapping.

Image Automation (Pipeline #4)

Added with the fix — infrastructure/automation/homepage/automation.yaml:

ResourceDetails
ImageRepositoryghcr.io/gethomepage/homepage, poll 1m
ImagePolicysemver range >=2.1.2 (floor = the outage fix pin)
ImageUpdateAutomationcommit chore: self-update homepage image [skip ci], path ./infrastructure/instances/homepage, strategy Setters

Unlike the other three pipelines (Docker Hub, numerical run-number tags), this pipeline polls GHCR and uses semver ordering. The automation has already bumped the live image from the manual pin v2.1.2 → v2.2.0 (marker at homepage.yaml: # {"$imagepolicy": "flux-system:homepage"}). See Image Automation Detail.

See Also