Hand-authored platform/vuln-scanner (non-gating Flux tier, digest-pinned Trivy 0.76.1 and python 3.14.9-alpine, read-only RBAC, per-pod oauth2-proxy, internal-only cve.<domain>), five alerts with promtool tests, R-VULN-01..09 registry entries, and vuln-* L0 checks with mutation self-tests. src/ and the bot workflow are integrated separately. Co-Authored-By: Claude Opus 5.5 <[email protected]>
163 lines
6.0 KiB
YAML
163 lines
6.0 KiB
YAML
---
|
|
# 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
|
|
# The CVE page (platform/vuln-scanner, docs/17): behind SSO, restricted to platform-admins.
|
|
# Homepage has no per-group surfaces, so this tile is shown to everyone who can open this
|
|
# dashboard; the page itself enforces platform-admins.
|
|
- CVE Report:
|
|
href: https://cve.${BASE_DOMAIN}
|
|
description: Container image CVE inventory (platform-admins)
|
|
icon: mdi-shield-bug
|
|
- 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: ""
|