From 9d92c4bd2125aac151e9401f3f172ec560c9d850 Mon Sep 17 00:00:00 2001 From: Vuong Hoang Date: Tue, 18 Aug 2026 19:12:02 -0700 Subject: [PATCH] fix(homepage): pin UltraSeedbox to one tab, dedupe Uptime Kuma, size columns to members MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit UltraSeedbox had no layout: entry, and Homepage renders an untabbed group on every tab — eight full-width bookmark bars repeated four times. Pinned to Main with a row layout. Uptime Kuma rendered twice: a manual services.yaml block under Monitoring plus homepage.group=Apps on the container. Dropped the manual block, moved the label to Monitoring, added homepage.siteMonitor. Adopted the previously unmanaged uptimekuma stack into stacks/ so the label is version-controlled. Column counts declared more columns than groups had members, leaving the last row of several groups mostly empty. Columns now track member counts. Also records an UNRESOLVED regression: since the container was recreated the client render has lost its tab bar, wallpaper and i18n. Ruled out the config changes (committed pre-cleanup config reproduces it) and v2.0.0 (v1.13.2 reproduces it). Server HTML still carries the tab markup, so the loss is client-side. Details in the stack README. --- stacks/homepage/README.md | 60 ++++++++++++++++++++++++++++++ stacks/homepage/conf/services.yaml | 20 +++++----- stacks/homepage/conf/settings.yaml | 42 ++++++++++++++++----- stacks/uptimekuma/README.md | 54 +++++++++++++++++++++++++++ stacks/uptimekuma/compose.yaml | 56 ++++++++++++++++++++++++++++ 5 files changed, 214 insertions(+), 18 deletions(-) create mode 100644 stacks/uptimekuma/README.md create mode 100644 stacks/uptimekuma/compose.yaml diff --git a/stacks/homepage/README.md b/stacks/homepage/README.md index d7edc21..b6d8e4b 100644 --- a/stacks/homepage/README.md +++ b/stacks/homepage/README.md @@ -62,6 +62,66 @@ rather than when the group is wrong. 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. +## 2026-08-18 cleanup + +Three fixes, all in this stack's config except where noted: + +- **UltraSeedbox appeared on all four tabs.** The bookmark group had no entry + in `settings.yaml`'s `layout:` block at all, and Homepage's documented + behaviour is that *"if a group has no tab specified (and tabs are set on + other groups), services and bookmarks will be shown on all tabs."* It now + carries `tab: Main` plus `style: row` / `columns: 4`, which also turns eight + full-width bars into a compact grid. **Any group added without a `tab:` will + do this again** — the rule is now written at the top of the layout block. +- **Uptime Kuma rendered twice.** It was listed manually under Monitoring in + `services.yaml` *and* labelled `homepage.group=Apps` on its container. The + manual block is gone; the container's label now says `Monitoring` and + carries `homepage.siteMonitor`. The container was adopted into this repo at + `stacks/uptimekuma/` in the same commit — it had been running unmanaged. +- **Column counts were fiction.** Several groups declared more columns than + they had members, so the last row of each was mostly dead space (Notes: 1 + card in a 4-wide row). Columns now track member counts; see the rule in + `settings.yaml`. Check with `GET /api/services`, which prints live per-group + counts. + +## ⚠ UNRESOLVED — the tab bar disappeared on container recreate + +**Status: open. The dashboard is degraded but usable.** Since the homepage +container was recreated on 2026-08-18, the client render has lost its tab bar, +its wallpaper, and its i18n. Groups render as side-by-side columns instead of +rows, and the search box shows the raw key `search.search`. Every service, +status pill and widget still works — it is a link board without tabs, not a +dead page. + +**What it is not** — both obvious suspects were tested and cleared: + +- **Not the config changes above.** Restoring `settings.yaml` *and* + `services.yaml` to their committed pre-cleanup versions reproduces the + breakage exactly. So does the pre-adoption backup config in + `/opt/docker-bu/conf/homepage/`. +- **Not the v2.0.0 release.** A throwaway container on `v1.13.2` (the last + v1, 2026-06-09) against the same config shows identical symptoms. The image + never changed anyway: the working container and the broken one both report + `v2.0.0` / rev `17456f2`, and only one homepage image exists on the host. + +**What is known.** The *server-rendered* HTML still contains the tab markup, +the wallhaven background URL and `useEqualHeights` — so `settings.yaml` is +being read and delivered correctly. The loss happens client-side, with **no +page error, no failed chunk and no non-200** beyond two unrelated Uptime Kuma +widget 403s. `GET /api/validate` returns `[]`. A fresh container never +renders tabs here regardless of image version, config version, `PUID`/`PGID`, +or whether Docker discovery is mounted at all. + +**The one thing that did work** was the container that had been up ~12 hours, +and it cannot be reproduced from image + config. The remaining hypothesis is +that its writable layer held state a fresh container does not rebuild — i.e. +something was changed inside the running container by hand at some point and +was never written back to `/opt/docker/conf/homepage`. If that is right, the +fix is to find out what, because the next recreate would have lost it anyway. + +Before/after evidence: `~/booth-data/homepage-cleanup/` on nh3-dev → +`http://10.100.10.50:8090/b/homepage-cleanup/` (24h TTL). + ## Open question `ESH-FileBot` (`10.0.50.70`) is still described as "role TBC" — it responds to diff --git a/stacks/homepage/conf/services.yaml b/stacks/homepage/conf/services.yaml index 35767eb..2a075cc 100644 --- a/stacks/homepage/conf/services.yaml +++ b/stacks/homepage/conf/services.yaml @@ -7,15 +7,17 @@ # 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) +# The Monitoring group is fully Docker-auto-discovered — Beszel, Dozzle, +# Backrest and Uptime Kuma all carry homepage.group=Monitoring on their +# compose files. There is deliberately no manual block here. +# +# Uptime Kuma used to be listed manually here AND labelled +# homepage.group=Apps on its container, so it rendered twice — once in +# Monitoring without its widget, once in Apps with it. Fixed 2026-08-18 by +# deleting the manual entry and moving the container's label to Monitoring +# (stacks/uptimekuma/). This is the exact failure the warning below +# describes; it survived the 2026-08-17 audit because a duplicate reads as +# two plausible cards rather than as an error. - Apps: # Manual entry — the Booth is a user-level systemd service on nh3-dev diff --git a/stacks/homepage/conf/settings.yaml b/stacks/homepage/conf/settings.yaml index d2f6799..c24ec14 100644 --- a/stacks/homepage/conf/settings.yaml +++ b/stacks/homepage/conf/settings.yaml @@ -44,19 +44,30 @@ useEqualHeights: true # 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. +# COLUMN COUNTS ARE NOT A STYLE CHOICE — they are the member count. +# `columns: N` lays the group out N-per-row and leaves the remainder of the +# last row as dead space. A 1-member group at columns:4 renders one card and +# three empty cells, which is what made this dashboard look ragged before +# 2026-08-18. Rule: set columns to the member count, or to the divisor that +# leaves the smallest remainder. Re-check when a group gains or loses a +# service — `GET /api/services` prints the live per-group counts. +# +# EVERY GROUP NEEDS A `tab:` — including bookmark groups. A group with no tab +# assignment renders on ALL FOUR TABS. That is how UltraSeedbox ended up +# repeated at the bottom of every tab (fixed 2026-08-18); it is Homepage +# behaviour, not a bug, and it will happen again to the next group added +# without a tab. layout: Notes: icon: mdi-note-text-outline tab: Main style: row - columns: 4 + columns: 1 News: icon: mdi-rss tab: Main style: row - columns: 4 + columns: 2 Monitoring: icon: mdi-chart-line tab: Main @@ -67,14 +78,27 @@ layout: tab: Main style: row columns: 4 + # 2 wide, not 3 — Plex and Jellyfin carry stat-block widgets that get + # squeezed to unreadable at 4-across, and 4 members / 3 columns orphaned + # Jellyfin onto a row of its own. Media: icon: mdi-play-box-multiple tab: Main style: row - columns: 3 + columns: 2 Games: icon: mdi-gamepad-square tab: Main + style: row + columns: 1 + # Bookmarks. Listed here for the tab pin above all else — without it this + # group appears on every tab. `style: row` also turns the eight entries + # from full-width stacked bars into a compact grid. + UltraSeedbox: + icon: mdi-download-network + tab: Main + style: row + columns: 4 # --- AI tab: the inference fleet, ordered core-models -> support -> apps --- AI - Inference: icon: mdi-brain @@ -90,12 +114,12 @@ layout: icon: mdi-router-network tab: AI style: row - columns: 3 + columns: 4 AI - Speech (TTS): icon: mdi-account-voice tab: AI style: row - columns: 3 + columns: 4 AI - Audio Tools: icon: mdi-waveform tab: AI @@ -123,12 +147,12 @@ layout: icon: si-proxmox tab: Infrastructure style: row - columns: 4 + columns: 3 Infra - IRV: icon: mdi-brain tab: Infrastructure style: row - columns: 4 + columns: 2 Infra - ESH: icon: si-proxmox tab: Infrastructure diff --git a/stacks/uptimekuma/README.md b/stacks/uptimekuma/README.md new file mode 100644 index 0000000..6e000f4 --- /dev/null +++ b/stacks/uptimekuma/README.md @@ -0,0 +1,54 @@ +# uptimekuma — service uptime monitor (esh-docker-vm) + +`louislam/uptime-kuma:latest` on **esh-docker-vm** (`10.0.50.45:3001`). Widget +slug `nethealth` feeds the Uptime Kuma card on the fleet dashboard. + +## Why it is in this repo + +Adopted 2026-08-18 while cleaning up Homepage. It had run unmanaged on the +host for ~12 months, and its `homepage.group=Apps` label put it in the wrong +dashboard group — where it collided with a *manual* entry for the same +service in the homepage stack's `services.yaml` under Monitoring. Result: two +Uptime Kuma cards on the Main tab, one with the widget and one without. + +That is precisely the "never list a labelled container manually" failure the +homepage README warns about, and it survived the 2026-08-17 audit because a +duplicate looks like two plausible cards rather than like an error. The fix +was to keep the label as the single source of truth, move it to `Monitoring`, +and delete the manual block. + +## Deviations from house convention (deliberate, not oversights) + +The compose was adopted as-run rather than normalised — this was a dashboard +fix, not a rewrite of a service that has been stable for a year: + +- `restart: always`, not `unless-stopped`. It revives on Docker daemon start + even if it was stopped on purpose. +- No `healthcheck:` block. The image ships its own, which is why `docker ps` + reports `healthy` anyway. + +Worth normalising on the next deliberate touch, not worth a restart today. + +## The container name + +Live container was `45d2522a8cb6_uptime-kuma` — Docker's collision rename from +some past recreate where the old container could not be removed. Recreating +under this compose restores the plain `uptime-kuma` name. Harmless either way. + +## Data + +All monitor definitions and history live in the named volume +`uptimekuma_uptime-kuma`. **Recreating the container is safe. Deleting that +volume loses every monitor and all history** — there is no config file to +restore from, the state is entirely in the volume's SQLite DB. + +## Deploy + +```bash +scripts/deploy-stack.sh esh-docker-vm uptimekuma --compose +ssh lkraven@10.0.50.45 'cd /opt/docker/compose/uptimekuma && docker compose up -d' +``` + +Label changes need a **recreate**, not a restart — Docker only applies labels +when the container is created. After recreating, the Homepage container also +needs a recreate before it re-reads the discovered set. diff --git a/stacks/uptimekuma/compose.yaml b/stacks/uptimekuma/compose.yaml new file mode 100644 index 0000000..5861321 --- /dev/null +++ b/stacks/uptimekuma/compose.yaml @@ -0,0 +1,56 @@ +# uptime-kuma — service uptime monitor on esh-docker-vm. +# +# Adopted into this repo 2026-08-18. It had been running unmanaged on the +# host since 2025 and was only noticed because its homepage label put it in +# the wrong group: it was ALSO listed manually in the homepage stack's +# services.yaml under Monitoring, so the dashboard rendered two Uptime Kuma +# cards — the labelled one in Apps (with the widget) and the manual one in +# Monitoring (without). The label is now the single source of truth and the +# manual entry is gone. +# +# ⚠️ The compose is preserved as it ran, not normalised. Two deliberate +# deviations from the house conventions, left alone because this commit is +# a homepage fix and not a rewrite of a service that has been up for a +# year: +# - `restart: always` rather than `unless-stopped` (always revives on +# daemon start even after a deliberate manual stop) +# - no healthcheck block (the image ships its own, which is why +# `docker ps` reports healthy) +# +# The data volume `uptimekuma_uptime-kuma` holds every monitor definition +# and all history. Recreating the container is safe; deleting that volume +# is not. + +name: uptimekuma + +services: + uptime-kuma: + image: louislam/uptime-kuma:latest + container_name: uptime-kuma + restart: always + ports: + - "3001:3001" + volumes: + - uptime-kuma:/app/data + labels: + # Monitoring, NOT Apps — this is the group the dashboard's own layout + # reserves for Backrest / Beszel / Dozzle / this. See the note above. + - homepage.group=Monitoring + - homepage.name=Uptime Kuma + - homepage.icon=mdi-arrow-up-bold-circle + - homepage.description=Service Monitoring (esh) + - homepage.href=http://10.0.50.45:3001 + - homepage.siteMonitor=http://10.0.50.45:3001 + - homepage.widget.type=uptimekuma + - homepage.widget.url=http://10.0.50.45:3001 + - homepage.widget.slug=nethealth + networks: + - tnet + +volumes: + uptime-kuma: {} + +networks: + tnet: + name: traefik-net + external: true