--- # Homepage configuration (gethomepage). Each key is mounted read-only into /app/config via a subPath # (deployment.yaml) — the exact file set the app expects (services/settings/bookmarks/widgets + # docker/kubernetes/proxmox + custom.css/js). Plain link tiles only: NO service-widget API keys are wired # here (that needs per-service secrets — flagged as a follow-up), so nothing sensitive lives in this # ConfigMap. Icons use the app-BUNDLED Material Design set (`mdi-*`) so no icon CDN is fetched and the # pod's egress stays DNS-only (networkpolicy.yaml). Brand icons (selfh.st/dashboard-icons) would need # world:443 egress — deliberately not used. apiVersion: v1 kind: ConfigMap metadata: name: homepage namespace: homepage labels: app.kubernetes.io/name: homepage data: settings.yaml: | --- title: Home Network headerStyle: clean theme: dark color: slate hideVersion: true layout: Platform: style: row columns: 3 Media: style: row columns: 3 Network & Infra: style: row columns: 3 services.yaml: | --- - Platform: - Headlamp: href: https://headlamp.${BASE_DOMAIN} description: Kubernetes dashboard (per-user OIDC RBAC) icon: mdi-kubernetes - Grafana: href: https://grafana.${BASE_DOMAIN} description: Metrics, logs & dashboards (fronts Prometheus/Loki/Alertmanager) icon: mdi-chart-areaspline - Semaphore: href: https://semaphore.${BASE_DOMAIN} description: Ansible automation & CI icon: mdi-cog-play - Gitea: href: https://gitea.${BASE_DOMAIN} description: Git hosting & Actions (GitOps source of truth) icon: mdi-git - Keycloak: href: https://keycloak.${BASE_DOMAIN} description: Identity provider (SSO / OIDC) icon: mdi-account-key - Media: - Plex: href: https://plex.${BASE_DOMAIN} description: Media streaming icon: mdi-plex - Seerr: href: https://seerr.${BASE_DOMAIN} description: Media requests icon: mdi-play-box-multiple - Sonarr: href: https://sonarr.${BASE_DOMAIN} description: TV library manager icon: mdi-television-classic - Radarr: href: https://radarr.${BASE_DOMAIN} description: Movie library manager icon: mdi-movie-open - Jackett: href: https://jackett.${BASE_DOMAIN} description: Indexer proxy icon: mdi-magnify - qBittorrent: href: https://qbittorrent.${BASE_DOMAIN} description: Download client (VPN egress) icon: mdi-download-network # Crafty Controller — a running, north-south-exposed web UI (platform/crafty/httproute.yaml, # reconciled by clusters/base/crafty.yaml) that this dashboard did NOT surface until # 2026-09-13. R-C2-01 says the root MUST surface "the services running in the cluster and # links to them", so an unsurfaced route is a requirement gap, not a styling preference — # conformance/tests/l0-static/c2-root-surface fails on one now. Grouped under Media because # it manages game servers; regrouping it under Platform would be purely cosmetic. The game # ports themselves (crafty-mc.${BASE_DOMAIN}, TCP 25565-25567 / UDP 19132-19134) are an L4 # LoadBalancer with no browsable URL, so this tile is how they are surfaced. - Crafty: href: https://crafty.${BASE_DOMAIN} description: Minecraft server manager (Keycloak-gated) icon: mdi-minecraft - Network & Infra: - Pi-hole: href: https://pihole.${BASE_DOMAIN} description: Network-wide DNS & ad-blocking icon: mdi-shield-check - UniFi: href: https://unifi.${BASE_DOMAIN}:11443 description: Network controller (UOS) icon: mdi-router-network - Nextcloud: href: https://nextcloud.${BASE_DOMAIN} description: Files, calendar & contacts icon: mdi-cloud bookmarks.yaml: | --- - Operations: - Gitea (external): - abbr: GT href: https://gitea.keithjackson.dev - Auth portal: - abbr: SSO href: https://auth.${BASE_DOMAIN} - Reference: - Homepage docs: - abbr: HP href: https://gethomepage.dev widgets.yaml: | --- - datetime: text_size: xl format: dateStyle: long timeStyle: short hour12: false - search: provider: duckduckgo target: _blank # No Docker integration (Homepage does not reach the Docker socket in-cluster). docker.yaml: | --- # No Kubernetes integration (no SA / cluster RBAC granted — avoids scope creep; the kubernetes # widget would need a read-only ServiceAccount. Left empty deliberately). kubernetes.yaml: | --- # No Proxmox integration. Homepage v2.1.2 treats proxmox.yaml as a REQUIRED config file (it is in # the image skeleton dir /app/src/skeleton) and copies a default skeleton into /app/config when it # is missing — which EACCES-crashes the pod because the config dir is a read-only subPath mount. # Provide it here (empty) so Homepage finds it and never writes at runtime. A live PVE widget would # need pve url/token/secret in a Secret — deliberately not wired. proxmox.yaml: | --- custom.css: "" custom.js: ""