From c5beeac32de388da57478726926b59e54ea56f89 Mon Sep 17 00:00:00 2001 From: Vuong Hoang Date: Mon, 17 Aug 2026 21:10:37 -0700 Subject: [PATCH] feat(homepage): bring the fleet dashboard under version control Homepage on esh-docker-vm:5100 was the one stack whose config lived only on the host, edited in place. Its version history was six hand-rolled services.yaml.bak-* files. Now canonical here and deployed with deploy-stack.sh like everything else; the .bak files are gone. Corrections from the audit: - ANA-Firewall described a 'Fortigate 81F'. It is a FortiGate-80F running FortiOS 7.2.10, verified live against the device. - NH3-Ansible pointed at 10.100.50.42 as an 'Ansible control node'. That host is nh3-extdev, the manager/external-dev successor after nh3-ansible was retired. Renamed and re-described. - Dropped the UltraSeedbox layout group: nothing provides it, so it only ever rendered empty. Adds .env.example and a README documenting the two-path service model (docker label discovery across five engines vs manual entries), the labels-only-apply- on-recreate rule, and the foot-guns found: HOMEPAGE_ALLOWED_HOSTS matches host AND port so a bare IP does not cover IP:port; :2375 is plaintext and unauthenticated on all five engines; ping: cards can only be judged from the dashboard host. Verified after deploy via /api/services: 105 cards across 19 groups, both corrections live, ana-docker discovery intact. --- stacks/homepage/.env.example | 13 ++ stacks/homepage/README.md | 60 +++++++ stacks/homepage/compose.yaml | 27 ++++ stacks/homepage/conf/bookmarks.yaml | 43 +++++ stacks/homepage/conf/custom.css | 2 + stacks/homepage/conf/custom.js | 2 + stacks/homepage/conf/docker.yaml | 38 +++++ stacks/homepage/conf/kubernetes.yaml | 4 + stacks/homepage/conf/proxmox.yaml | 14 ++ stacks/homepage/conf/services.yaml | 226 +++++++++++++++++++++++++++ stacks/homepage/conf/settings.yaml | 146 +++++++++++++++++ stacks/homepage/conf/widgets.yaml | 11 ++ 12 files changed, 586 insertions(+) create mode 100644 stacks/homepage/.env.example create mode 100644 stacks/homepage/README.md create mode 100644 stacks/homepage/compose.yaml create mode 100644 stacks/homepage/conf/bookmarks.yaml create mode 100644 stacks/homepage/conf/custom.css create mode 100644 stacks/homepage/conf/custom.js create mode 100644 stacks/homepage/conf/docker.yaml create mode 100644 stacks/homepage/conf/kubernetes.yaml create mode 100644 stacks/homepage/conf/proxmox.yaml create mode 100644 stacks/homepage/conf/services.yaml create mode 100644 stacks/homepage/conf/settings.yaml create mode 100644 stacks/homepage/conf/widgets.yaml diff --git a/stacks/homepage/.env.example b/stacks/homepage/.env.example new file mode 100644 index 0000000..dd8282b --- /dev/null +++ b/stacks/homepage/.env.example @@ -0,0 +1,13 @@ +# homepage — tunables. Real .env lives on esh-docker-vm at +# /opt/docker/compose/homepage/.env and is NEVER committed. + +# Host validation. Homepage matches the Host header INCLUDING THE PORT, so a +# bare IP does NOT cover the IP:port form -- `10.0.50.45` alone still rejects +# http://10.0.50.45:5100/ with "Host validation failed". List every host:port +# combination the dashboard is actually reached by. +HOMEPAGE_ALLOWED_HOSTS=eshhome,eshhome.esteban.net,10.0.50.45,10.0.50.45:5100,localhost:5100 + +# Media widget API keys — referenced from services.yaml as +# {{HOMEPAGE_VAR_PLEX_KEY}} / {{HOMEPAGE_VAR_JELLYFIN_KEY}} +HOMEPAGE_VAR_PLEX_KEY= +HOMEPAGE_VAR_JELLYFIN_KEY= diff --git a/stacks/homepage/README.md b/stacks/homepage/README.md new file mode 100644 index 0000000..043ed89 --- /dev/null +++ b/stacks/homepage/README.md @@ -0,0 +1,60 @@ +# homepage — the fleet dashboard + +`ghcr.io/gethomepage/homepage` on **esh-docker-vm** (`10.0.50.45:5100`), behind +Traefik as `eshhome` / `eshhome.esteban.net`. Config is plain YAML — no +database, no UI-written state — which is why it belongs in this repo like any +other stack. + +**Brought under version control 2026-08-17.** Before that it was edited in +place on the host, and had accumulated six hand-rolled `services.yaml.bak-*` +files as its only version history. Those were removed; git is the history now. +Edit here, then `scripts/deploy-stack.sh esh-docker-vm homepage`. + +## How services get on the dashboard + +Two paths, and mixing them is the classic failure: + +1. **Docker label auto-discovery** — the default. A stack carries + `homepage.group=` / `homepage.name=` / `homepage.icon=` / `homepage.description=` + / `homepage.href=` labels and appears automatically. `conf/docker.yaml` + wires **five** engines over plaintext `:2375`: esh-docker-vm, ana-docker, + nh3-docker, ana-ml2, irv-ml1. +2. **Manual entries in `conf/services.yaml`** — for anything that is not a + labelled container on one of those five hosts: hardware, BMCs, hypervisors, + printers, and user-level systemd services (The Booth, Voice Design Studio). + +⚠ **Never list a labelled container manually — it renders twice.** The +comments in `services.yaml` mark which groups are auto-populated (AI ×7, +Service Networking, Monitoring). Respect them. + +⚠ **Labels only apply on container recreate.** Changing `homepage.group=` on a +compose file and running `restart` does nothing; the container must be +recreated. + +## Layout + +`conf/settings.yaml` owns tabs, group order, and column counts — `services.yaml` +owns *what exists*, `settings.yaml` owns *where it sits*. Four tabs: Main, AI, +Infrastructure, Toolchain. A group listed in `layout:` with no members simply +renders empty, so a group can look "dead" when its provider host is unreachable +rather than when the group is wrong. + +## Foot-guns found in the 2026-08-17 audit + +- **`HOMEPAGE_ALLOWED_HOSTS` matches host *and port*.** The entry `10.0.50.45` + does **not** cover `http://10.0.50.45:5100/` — that combination was being + rejected with `Host validation failed` in the container log while the Traefik + hostnames worked fine. Every `host:port` the dashboard is reached by needs + its own entry. See `.env.example`. +- **`:2375` is plaintext and unauthenticated** on all five engines. Fine on a + trusted LAN, and unchanged by this commit, but it is real exposure: anything + that can reach those ports has full Docker control of that host. `docker.yaml` + carries a commented TLS example for when that stops being acceptable. +- **`ping:` cards can only be judged from esh-docker-vm.** Probing them from + another box gives false FAILs — ICMP is filtered across some site links. All + 34 entries were verified reachable *from the dashboard host* on 2026-08-17. + +## Open question + +`ESH-FileBot` (`10.0.50.70`) is still described as "role TBC" — it responds to +ping, but nobody has written down what it does. Worth resolving or removing. diff --git a/stacks/homepage/compose.yaml b/stacks/homepage/compose.yaml new file mode 100644 index 0000000..2f22bf5 --- /dev/null +++ b/stacks/homepage/compose.yaml @@ -0,0 +1,27 @@ +services: + homepage: + image: ghcr.io/gethomepage/homepage:latest + container_name: homepage + environment: + PUID: 1000 + PGID: 1000 + ports: + - 5100:3000 + volumes: + - /opt/docker/conf/homepage:/app/config # Make sure your local config directory exists + - /var/run/docker.sock:/var/run/docker.sock:ro # optional, for docker integrations + restart: unless-stopped + networks: + - tnet + labels: + - traefik.enable=true + - traefik.http.routers.homepage.rule=host(`eshhome`) || host(`10.0.50.45`) + || host (`eshhome.esteban.net`) + - traefik.http.services.homepage.loadbalancer.server.port=3000 + - traefik.http.routers.homepage.priority=1 + env_file: + - .env +networks: + tnet: + name: traefik-net + external: true diff --git a/stacks/homepage/conf/bookmarks.yaml b/stacks/homepage/conf/bookmarks.yaml new file mode 100644 index 0000000..8df6eae --- /dev/null +++ b/stacks/homepage/conf/bookmarks.yaml @@ -0,0 +1,43 @@ +# https://gethomepage.dev/latest/configs/bookmarks + +- UltraSeedbox: + - Control Panel: + - abbr: CP + icon: si-bittorrent + href: http://cp.ultra.cc/ + description: Ultraseedbox Control Panel + - FileZilla: + - abbr: fz + icon: si-filezilla + href: http://10.0.50.154:5800 + description: FTP Client + - ruTorrent: + - abbr: rt + icon: si-bittorrent + href: https://lkraven.hebe.usbx.me/rutorrent/ + description: ruTorrent Client + - Sonarr: + - abbr: sr + icon: si-sonarr + href: https://lkraven.hebe.usbx.me/sonarr/ + description: TV Shows + - Radarr: + - abbr: rr + icon: si-radarr + href: https://lkraven.hebe.usbx.me/radarr/ + description: Movies + - Bazarr: + - abbr: br + icon: mdi-subtitles + href: https://lkraven.hebe.usbx.me/bazarr/ + description: Subtitles + - Sabnzbd: + - abbr: nz + icon: mdi-newspaper + href: https://lkraven.hebe.usbx.me/sabnzbd + description: Newz Client + - Seedsync: + - abbr: sy + icon: mdi-download-box + href: http://10.0.50.51:8800/dashboard + description: Sync Client diff --git a/stacks/homepage/conf/custom.css b/stacks/homepage/conf/custom.css new file mode 100644 index 0000000..fcc7889 --- /dev/null +++ b/stacks/homepage/conf/custom.css @@ -0,0 +1,2 @@ +/* Custom styling for homepage. Empty placeholder — keep file present so + * homepage doesn't 404 on the asset. */ diff --git a/stacks/homepage/conf/custom.js b/stacks/homepage/conf/custom.js new file mode 100644 index 0000000..b377919 --- /dev/null +++ b/stacks/homepage/conf/custom.js @@ -0,0 +1,2 @@ +// Custom JS for homepage. Empty placeholder — keep file present so +// homepage doesn't 404 on the asset. diff --git a/stacks/homepage/conf/docker.yaml b/stacks/homepage/conf/docker.yaml new file mode 100644 index 0000000..f47ca10 --- /dev/null +++ b/stacks/homepage/conf/docker.yaml @@ -0,0 +1,38 @@ +--- +# https://gethomepage.dev/latest/configs/docker/ +# +# All four Docker hosts expose the engine on port 2375. This is plaintext +# and works fine on a trusted LAN; if any host is ever exposed or shared, +# switch to a TLS socket (examples commented below). + +esh-vm-docker: + host: 10.0.50.45 + port: 2375 + +ana-pfi-docker: + host: 10.250.50.70 + port: 2375 + +nh3-pfi-docker: + host: 10.100.50.40 + port: 2375 + +ana-ml2-docker: + host: 10.250.50.54 + port: 2375 + +# irv-ml1 — reachable ONLY via WireGuard tunnel, so docker auto-discovery +# traffic traverses the tunnel. If WG drops, homepage will show irv-ml1 +# services as offline until reconnect. +irv-ml1-docker: + host: 10.100.79.3 + port: 2375 + +# Example TLS socket (if/when a host moves off plaintext 2375): +# ana-pfi-docker: +# host: 10.250.50.70 +# port: 2376 +# tls: +# keyFile: docker-tls/ana-docker/key.pem +# caFile: docker-tls/ana-docker/ca.pem +# certFile: docker-tls/ana-docker/cert.pem diff --git a/stacks/homepage/conf/kubernetes.yaml b/stacks/homepage/conf/kubernetes.yaml new file mode 100644 index 0000000..50473d7 --- /dev/null +++ b/stacks/homepage/conf/kubernetes.yaml @@ -0,0 +1,4 @@ +--- +# https://gethomepage.dev/latest/configs/kubernetes +# No Kubernetes cluster in the fleet. Keep file present so homepage +# doesn't warn on startup. diff --git a/stacks/homepage/conf/proxmox.yaml b/stacks/homepage/conf/proxmox.yaml new file mode 100644 index 0000000..65f9c9e --- /dev/null +++ b/stacks/homepage/conf/proxmox.yaml @@ -0,0 +1,14 @@ +--- +# https://gethomepage.dev/latest/widgets/services/proxmox +# Not wired up yet. To use per-node widgets, create an API token on each +# PVE node (Datacenter -> Permissions -> API Tokens) and define an entry +# per hypervisor here: +# +# pfi-pve: +# url: https://10.250.250.31:8006 +# token: 'homepage@pam!hp' +# secret: '{{HOMEPAGE_VAR_PFI_PVE_TOKEN}}' +# +# nh3-pve: ... +# esh-pve: ... +# esh-pve-nas: ... diff --git a/stacks/homepage/conf/services.yaml b/stacks/homepage/conf/services.yaml new file mode 100644 index 0000000..35767eb --- /dev/null +++ b/stacks/homepage/conf/services.yaml @@ -0,0 +1,226 @@ +--- +# https://gethomepage.dev/latest/configs/services +# +# Groups are ordered by settings.yaml `layout`. This file holds the manual +# entries — infrastructure, BMCs, off-Docker endpoints, and a handful of +# well-known internal service URLs. Docker-labeled stacks auto-populate +# their own groups through the providers in docker.yaml, so most app +# entries don't need to appear here. + +- Monitoring: + # Beszel, Dozzle, Backrest arrive here via Docker label auto-discovery + # (homepage.group=Monitoring on their compose files). Do not re-add them + # manually — they'll double up in the UI. + - Uptime Kuma: + href: http://10.0.50.45:3001 + icon: mdi-check-network + siteMonitor: http://10.0.50.45:3001 + description: Uptime monitor (esh-docker-vm) + +- Apps: + # Manual entry — the Booth is a user-level systemd service on nh3-dev + # (not a Docker-labeled stack), so it can't auto-discover; list it here. + - The Booth: + href: http://10.100.10.50:8090/ + icon: mdi-filmstrip + siteMonitor: http://10.100.10.50:8090/healthz + description: Ephemeral media drop + upload-for-pickup (human-readable ids) — nh3-dev, 24h TTL + - Voice Design Studio: + href: http://10.100.79.3:8216/ + icon: mdi-microphone + siteMonitor: http://10.100.79.3:8216/health + description: Mint, audition and keeper-mark synthetic fleet voices — irv-ml1, CPU-only + - The Henge: + href: http://park.phasefinal.com:8420/ + icon: mdi-clipboard-check + siteMonitor: http://park.phasefinal.com:8420/healthz + description: Durable needs-attention / idea parking (stonehenge-park) — ana-docker + +# The AI tab is fully Docker-auto-discovered. Each inference service carries +# a homepage.group=AI - label on its compose file (AI - Inference, +# AI - Eval & Retrieval, AI - Gateways & Chat, AI - Speech (TTS), +# AI - Audio Tools, AI - Image & Media). Tab assignment, group order, and +# column counts live in settings.yaml. Do not add entries here or they'll +# double up. To move a service between AI groups, change the label on its +# compose file and recreate the container (labels only apply on recreate). + +- Media: + - Plex: + href: http://10.0.50.56:32400 + icon: si-plex + siteMonitor: http://10.0.50.56:32400 + description: Media Server (esh-nas-pve 10.0.50.56) + widget: + type: plex + url: http://10.0.50.56:32400 + key: '{{HOMEPAGE_VAR_PLEX_KEY}}' + - Jellyfin: + href: http://10.0.50.57:8096 + icon: si-jellyfin + siteMonitor: http://10.0.50.57:8096 + description: Media Server (esh-nas-pve 10.0.50.57) + widget: + type: jellyfin + url: http://10.0.50.57:8096 + key: '{{HOMEPAGE_VAR_JELLYFIN_KEY}}' + enableBlocks: true + +- Games: + - Pterodactyl: + href: http://10.250.50.55/ + icon: mdi-gamepad-square + siteMonitor: http://10.250.50.55 + description: Game server panel + +- Infra - ANA: + - ANA-Firewall: + href: https://10.250.250.1 + icon: mdi-wall-fire + siteMonitor: https://10.250.250.1 + description: ana-gw FortiGate-80F, FortiOS 7.2.10 (ana-fw.phasefinal.com) + - PFI-r750xs-iDRAC: + href: https://10.250.250.30/ + siteMonitor: https://10.250.250.30/ + icon: si-dell + description: iDRAC (Dell R750xs) — OOB for pfi-pve @ 10.250.250.31 + - PFI-PVE: + href: https://10.250.250.31:8006/ + siteMonitor: https://10.250.250.31:8006/ + icon: si-proxmox + description: Proxmox hypervisor (pfi-pve) + - ANA-NAS: + href: https://10.250.50.50:9090/ + siteMonitor: https://10.250.50.50:9090/ + icon: mdi-nas + description: Debian NAS (Cockpit) + - ANA-FileBot: + ping: 10.250.50.53 + icon: mdi-sync-circle + description: File-task VM + - PFI-VM-Docker: + href: http://10.250.50.70:5001 + icon: si-docker + siteMonitor: http://10.250.50.70:5001 + description: Docker VM (ana-docker, Dockge at :5001) + - PFI-ANA-ML2: + ping: 10.250.50.54 + icon: mdi-brain + description: GPU host (bare-metal) + - PFI-ANA-ML2 BMC: + href: https://10.250.250.50 + icon: mdi-brain + siteMonitor: https://10.250.250.50 + description: BMC (ana-ml2) + - SFsrv-ANA: + href: https://10.250.250.115:8006 + icon: si-proxmox + siteMonitor: https://10.250.250.115:8006 + description: Proxmox (SureFire tenant hypervisor at PFI colo) + - SF-R630-iDRAC: + href: https://10.250.250.110/ + icon: si-dell + ping: 10.250.250.110 + description: Dell R630 iDRAC (SureFire tenant hardware) + - PBS-ANA: + href: https://10.250.50.90:8007/ + icon: mdi-backup-restore + siteMonitor: https://10.250.50.90:8007/ + description: Proxmox Backup Server — primary (fleet vzdump target) + +- Infra - NH3: + # NH3-Firewall (Fortigate 101F at 10.100.250.1) retired 2026-04-21, + # replaced by PFI-UDMSE (UniFi UDM Pro SE at 10.100.0.1, below). + # NH3-SW1 (Mikrotik CRS328-24P-4S+ at 10.100.250.2) retired from + # homepage 2026-04-22. + - PFI-UDMSE: + href: https://10.100.0.1 + icon: si-ubiquiti + siteMonitor: https://10.100.0.1 + description: UniFi Dream Machine Pro SE — gateway + controller (NH3 edge) + - NH3-NAS: + href: https://10.100.50.50:5001 + icon: mdi-nas + siteMonitor: https://10.100.50.50:5001 + description: Synology RS2418+ DSM (restic target + VM storage) + - NH3-PVE: + href: https://10.100.250.60:8006/ + siteMonitor: https://10.100.250.60:8006/ + icon: si-proxmox + description: Proxmox hypervisor (nh3-pve) + - NH3-VM-Docker: + href: http://10.100.50.40:5001 + icon: si-docker + siteMonitor: http://10.100.50.40:5001 + description: Docker VM (nh3-docker, Dockge at :5001) + - NH3-ExtDev: + ping: 10.100.50.42 + icon: mdi-laptop + description: Manager / external-dev box (nh3-extdev, Debian 13) — successor to the retired nh3-ansible + - PBS-NH3: + href: https://10.100.50.90:8007/ + icon: mdi-backup-restore + siteMonitor: https://10.100.50.90:8007/ + description: Proxmox Backup Server — DR mirror (pulls from PBS-ANA) + +- Infra - IRV: + # Irvine site — reachable only via WireGuard tunnel from NH3. + # The 10.100.79.0/24 subnet is the WG tunnel IP space; these cards + # only light up when the WG link is healthy. + - IRV-ML1: + ping: 10.100.79.3 + icon: mdi-brain + description: GPU host (bare-metal, RTX 3090 + RTX A6000, native AI stacks) + - IRV-ML1-Dockge: + href: http://10.100.79.3:5001 + icon: si-docker + siteMonitor: http://10.100.79.3:5001 + description: Docker management (irv-ml1) + +- Infra - ESH: + - ESH-UDMPM: + href: https://10.0.0.1 + icon: si-ubiquiti + siteMonitor: https://10.0.0.1 + description: UniFi Dream Machine Pro Max — gateway + controller (ESH) + - ESH-Firewall: + href: https://10.0.250.1 + icon: mdi-wall-fire + siteMonitor: https://10.0.250.1 + description: esh-gw + - Brother Printer: + href: http://10.0.90.125/ + icon: mdi-printer + siteMonitor: http://10.0.90.125/ + description: Brother (ESH) + - ESH-NAS: + href: https://10.0.50.50:9090 + icon: mdi-nas + siteMonitor: https://10.0.50.50:9090 + description: NAS share manager (Cockpit) + - ESH-PVE: + href: https://10.0.250.35:8006 + siteMonitor: https://10.0.250.35:8006 + icon: si-proxmox + description: Proxmox hypervisor (esh-pve) + - ESH-PVE-NAS: + href: https://10.0.50.55:8006 + siteMonitor: https://10.0.50.55:8006 + icon: si-proxmox + description: Proxmox hypervisor (esh-pve-nas, storage/media) + - ESH-FileBot: + ping: 10.0.50.70 + icon: mdi-sync-circle + description: Restic / file-sync VM (esh-nas-pve) — role TBC + - ESH-VM-Docker: + href: http://10.0.50.45:5001 + icon: si-docker + siteMonitor: http://10.0.50.45:5001 + description: Docker VM (esh-docker-vm, Dockge at :5001) + +# Service Networking group is now fully Docker-auto-discovered (Traefik ×2, +# AdGuard ×2, Dockge ×5, rest-server-ana, mailrise, etc. all carry +# homepage.group=Service Networking on their compose files). Position and +# layout live in settings.yaml. Do not add entries here or they'll double up. +# +# Mosquitto (ESH) note: still labeled Apps on its compose; once moved to +# Service Networking via a label change on esh-docker-vm, it auto-populates. diff --git a/stacks/homepage/conf/settings.yaml b/stacks/homepage/conf/settings.yaml new file mode 100644 index 0000000..d2f6799 --- /dev/null +++ b/stacks/homepage/conf/settings.yaml @@ -0,0 +1,146 @@ +--- +# https://gethomepage.dev/latest/configs/settings +title: ... all my base ... +theme: dark +color: slate +background: + image: https://w.wallhaven.cc/full/p9/wallhaven-p9gr2p.jpg + blur: sm + opacity: 20 +headerStyle: boxedWidgets + +providers: + openweathermap: openweathermapapikey + weatherapi: weatherapiapikey + +quicklaunch: + searchDescriptions: true + hideInternetSearch: true + showSearchSuggestions: true + hideVisitURL: true + +showStats: false +statusStyle: "" + +# Force all cards in a row to match the tallest card's height. Without +# this, widget-bearing cards (Plex stats, Traefik metrics) stand taller +# than plain link cards and the grid looks ragged. +useEqualHeights: true + +# Function-first layout, four-tab split: +# Main - daily-use apps, media, bookmarks, monitoring +# AI - the inference fleet, grouped by role (see below) +# Infrastructure - hardware, hypervisors, BMCs (per site) +# Toolchain - backend services running but rarely clicked +# +# The AI tab splits the fleet by function so a 20+ service list reads as +# sorted groups instead of one endless column. Group membership is set by +# the homepage.group=AI - label on each service's compose file: +# 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) +# +# Row counts target ~4-per-row so dense groups (Apps, Service Networking) +# read as a grid instead of an endless column. +layout: + Notes: + icon: mdi-note-text-outline + tab: Main + style: row + columns: 4 + News: + icon: mdi-rss + tab: Main + style: row + columns: 4 + Monitoring: + icon: mdi-chart-line + tab: Main + style: row + columns: 4 + Apps: + icon: mdi-apps + tab: Main + style: row + columns: 4 + Media: + icon: mdi-play-box-multiple + tab: Main + style: row + columns: 3 + Games: + icon: mdi-gamepad-square + tab: Main + # --- AI tab: the inference fleet, ordered core-models -> support -> apps --- + AI - Inference: + icon: mdi-brain + tab: AI + style: row + columns: 4 + AI - Eval & Retrieval: + icon: mdi-scale-balance + tab: AI + style: row + columns: 5 + AI - Gateways & Chat: + icon: mdi-router-network + tab: AI + style: row + columns: 3 + AI - Speech (TTS): + icon: mdi-account-voice + tab: AI + style: row + columns: 3 + AI - Audio Tools: + icon: mdi-waveform + tab: AI + style: row + columns: 2 + AI - Image & Media: + icon: mdi-image-multiple + tab: AI + style: row + columns: 2 + # Stopped stacks kept for rollback / superseded seats / retired auditions. + # They stay 'created' (not running) via `docker compose up --no-start`, so + # they show here as offline cards and revive with `docker compose start`. + AI - Dormant: + icon: mdi-sleep + tab: AI + style: row + columns: 4 + Infra - ANA: + icon: si-proxmox + tab: Infrastructure + style: row + columns: 4 + Infra - NH3: + icon: si-proxmox + tab: Infrastructure + style: row + columns: 4 + Infra - IRV: + icon: mdi-brain + tab: Infrastructure + style: row + columns: 4 + Infra - ESH: + icon: si-proxmox + tab: Infrastructure + style: row + columns: 4 + Service Networking: + icon: mdi-transit-connection-variant + tab: Toolchain + style: row + columns: 4 + Toolchain: + icon: mdi-toolbox + tab: Toolchain + style: row + columns: 4 diff --git a/stacks/homepage/conf/widgets.yaml b/stacks/homepage/conf/widgets.yaml new file mode 100644 index 0000000..63e4b15 --- /dev/null +++ b/stacks/homepage/conf/widgets.yaml @@ -0,0 +1,11 @@ +--- +# https://gethomepage.dev/latest/configs/service-widgets + +- resources: + cpu: true + memory: true + disk: / + +- search: + provider: duckduckgo + target: _blank