# homepage Canonical copies of the [gethomepage.dev](https://gethomepage.dev/) config for the fleet dashboard running on `esh-docker-vm` (`10.0.50.45`). ## What lives here | File | Purpose | |---|---| | `settings.yaml` | Title, theme, background, quick-launch, group layout | | `services.yaml` | Manual entries — infra, BMCs, off-Docker endpoints, fleet hubs | | `bookmarks.yaml` | External links (UltraSeedbox, etc.) | | `widgets.yaml` | Top-of-page widgets (resource panel, search) | | `docker.yaml` | Per-host Docker socket providers for label-based auto-discovery | | `kubernetes.yaml`, `proxmox.yaml` | Empty / sample — kept so homepage doesn't warn on startup | | `custom.css`, `custom.js` | Placeholders | | `.env.example` | Template for widget secrets (Plex, Jellyfin, eventual Proxmox tokens) | The real `.env` (with Plex + Jellyfin keys) lives on `esh-docker-vm` next to the compose file and is gitignored. ## Layout convention `settings.yaml` drives the group layout across four tabs: ``` tab: Main Notes / News / Monitoring / Apps / Media / Games / UltraSeedbox tab: AI (the inference fleet, sorted by role) AI - Inference LLM seats you call (gen, char-rp, char-rp-reasoning, summarizer) AI - Eval & Retrieval judges, reward, rerank, embed, image-quality AI - Gateways & Chat routing gateway, control plane, chat frontends AI - Speech (TTS) text-to-speech engines AI - Audio Tools speech-to-text + audio dataset tooling AI - Image & Media image/video generation + pipelines AI - Dormant stopped stacks (rollback seats, retired auditions) tab: Infrastructure Infra - ANA / NH3 / IRV / ESH hardware + hypervisors + BMCs, per site tab: Toolchain Service Networking / Toolchain plumbing, rarely clicked ``` The AI tab replaced the old single flat `AI Systems` group (2026-07-14): a 20+ service list read as one endless column, so it was split by function. Group membership is the `homepage.group=AI - ` label on each compose file; a label change only takes effect when the container is recreated (`docker compose up -d `, or `up --no-start ` to relabel a stopped stack without starting it). - **Manual entries** (this file) cover things without a Docker label: firewalls, switches, NAS web UIs, BMCs, hypervisors, and the cross-site hubs where direct IP:port URLs are stable. - **Docker-labeled stacks** auto-populate their group via the providers in `docker.yaml`. To drop a new service into a group, add `homepage.group=` (plus `.name`, `.icon`, `.description`, `.href`) labels to its compose file and redeploy. ## Placement rule (for new entries) When deciding where a service lands, ask **function first**: 1. Does it watch or back up the fleet? -> `Monitoring` 2. Is it an inference / model service? -> the matching `AI - ` group (Inference / Eval & Retrieval / Gateways & Chat / Speech (TTS) / Audio Tools / Image & Media); a stopped-but-kept stack -> `AI - Dormant` 3. Is it a user-facing app? -> `Apps` 4. Is it media / games? -> `Media` or `Games` 5. Is it a piece of hardware or a hypervisor? -> `Infra - ` 6. Is it toolchain / plumbing (no human interaction on the golden path)? -> `Service Networking` Site-specific sub-grouping is used for `Infra -` (device inventory maps to physical sites) and role-based sub-grouping for `AI -` (the fleet is large enough to warrant it). Other app groups are function-only. ## Deploying changes These files are the **canonical source** for the homepage config. The homepage compose file itself lives on `esh-docker-vm` (not yet tracked in this repo as a stack), so the usual `scripts/deploy-stack.sh` flow doesn't apply here yet. Current workflow — push this directory onto the host: ```bash rsync -av --delete \ --exclude='.env' --exclude='.env.*' \ --exclude='*.bak*' --exclude='logs/' \ configs/homepage/ esh-docker-vm:/opt/docker/conf/homepage/ ``` The real `.env` lives on `esh-docker-vm` next to the compose file and must not be overwritten (holds Plex/Jellyfin keys). > **`--delete` footgun (learned 2026-07-20):** the host keeps dated > `services.yaml.bak-*` safety copies and a live `logs/` dir that are *not* > in this repo. A bare `--delete` rsync wipes both. The `--exclude='*.bak*'` > and `--exclude='logs/'` above protect them. For a one-file tweak, skip > `--delete` entirely and push the single file: > `rsync -av configs/homepage/services.yaml esh-docker-vm:/opt/docker/conf/homepage/services.yaml` > (back up the host copy first: `ssh esh-docker-vm 'cp -a …/services.yaml …/services.yaml.bak--'`). The homepage container reloads most files on-change; if a new group in `settings.yaml` doesn't show up, `docker compose restart` on the host. **Follow-up:** once the homepage compose file is pulled into `stacks/homepage/compose.yaml`, move these files to `stacks/homepage/conf/` and drop this ad-hoc rsync in favor of `scripts/deploy-stack.sh`. ## Secrets / env substitution Any config can reference `{{HOMEPAGE_VAR_NAME}}` and homepage will substitute from the container env at render time. Current uses: - `HOMEPAGE_VAR_PLEX_KEY` (services.yaml -> Plex widget) - `HOMEPAGE_VAR_JELLYFIN_KEY` (services.yaml -> Jellyfin widget) Keep these out of the tracked YAML; only `.env.example` ships the names.