Skip to content

ADR 0003 — Homepage in production, custom dashboard kept as experimental

  • Status: Accepted (keep both — deploy only Homepage)
  • Date: 2026-04-16

Context

Two dashboards exist in the repo for sh.h5h.me:

  1. Homepage (ghcr.io/gethomepage/homepage:latest) — deployed via docker-compose.yml, configured in docker/homepage/*.yaml.
  2. Custom React app (code/apps/dashboard/) — its own Dockerfile + nginx.conf, not referenced in compose, not deployed anywhere.

A naive reader sees both and wonders which one is canonical. This ADR makes the answer explicit.

Decision

  • Production = Homepage. It is the service at sh.h5h.me.
  • apps/dashboard/ is kept as an experimental/future replacement. It is built in CI (so it doesn't bit-rot) but never deployed.

Reasoning

Homepage today gives us:

  • Declarative YAML config (easy diff review in PRs).
  • Native widgets for every service in the stack (Traefik, Authentik, Immich, Nextcloud, Plex, qBittorrent, Grafana, Prometheus, CrowdSec, Cloudflared, Tailscale, Loki, Docker).
  • Active upstream; weekly Dependabot bumps.

The custom dashboard adds work without adding value yet. Rebuilding all those widgets from scratch is a multi-week effort. The only features Homepage is missing for this stack are:

  • Authentik-group-aware UI (hide Admin tile from non-admins, without a second forward-auth middleware).
  • Shared theme tokens with the portfolio (h5h.me).
  • Avoiding the Docker socket mount.

If any of those become sharp enough to hurt, apps/dashboard/ is the migration target. See apps/dashboard/README.md for the migration steps.

Consequences

  • Two UIs live in the repo; readers must know only Homepage deploys. This ADR, the README in apps/dashboard/, and the service_catalog.md all flag the distinction.
  • CI builds both (npm run build:all) so an experimental change doesn't break silently.
  • If apps/dashboard/ stays dormant for > 6 months, reconsider deleting it rather than carrying dead code.

MIT License