--- type: aar status: harvested date: 2026-08-02 related: [] --- # AAR — Wiki-Rollout, Themes und Desktop-Clients (Nacht 2026-08-01/02) **Datum:** 2026-08-01 22:00 – 2026-08-02 09:30 · **Beteiligt:** sorb + Mac-Session **Umfang:** Wiki-Konsolidierung, Docusaurus-Deploy, BookStack-Gegenentwurf, 11 neue Themes, Desktop-Clients für vier Plattformen, Rebrand-Start ## 1. Ergebnis | Was | Stand | |---|---| | gitops-Wiki (15 Seiten) auf git.lab, inhaltlich korrigiert | ✅ | | Docusaurus-Wiki unter `axionwiki.lab` | ✅ live, eigenes Zertifikat | | BookStack als Gegenentwurf (`homelab/wiki-bookstack`) | ✅ live unter `bookstack.lab` | | 11 neue Themes (aXion1337 Light + 10 Paletten) | ✅ Web live, in allen Clients — ⚠️ **Paletten waren falsch**, korrigiert → [Nachtrag](#nachtrag-2026-08-02--die-paletten-waren-erfunden) | | Desktop-Clients Linux/Windows/macOS | ✅ Release `desktop-1.12.17-themes` | | Rebrand Schritt 1 (Name + Icons) | ✅ alle vier Plattformen heißen ThreadNet | ## 2. Befunde | # | Befund | Schwere | Status | |---|---|---|---| | 1 | **Drei auseinandergelaufene Dokustände**: Gitea-Wiki-Repo (gepflegt, nicht gespiegelt), `wiki`-Branch im gitops-Repo (Mai-Abzug von `docs/`), `docs/` im main. Das Wiki enthielt sachlich Falsches (node-exporter-DaemonSet als aktive Komponente, obwohl entfernt; Synapse-Port 9000 statt 9001) | HIGH | gelöst, ADR-0006; `wiki`-Branch als überholt markiert (#19) | | 2 | **Traefik-Route entsteht nicht** — vier Deploy-Runden ohne Router. Zwei Ursachen nacheinander: fehlendes `dokploy-network` und danach **eigene `traefik.*`-Labels neben denen von Dokploy** | HIGH | gelöst; Merksatz unten | | 3 | **`/favicon.ico` lieferte HTTP 200 mit `text/html`** — die nginx-`try_files`-Kette gab die 404-Seite mit Erfolgsstatus aus. Safari hielt das Icon für vorhanden und zeigte den Buchstaben-Fallback | MEDIUM | gelöst: Datei im Wurzelverzeichnis + `try_files $uri =404` für Assets | | 4 | **CI-Job-Container kennt die Lab-CA nicht** (`unable to get local issuer certificate`); der erste Fix als globale CI-Variable brach den Checkout des eigenen Repos | MEDIUM | gelöst: CA im Repo, `GIT_SSL_CAINFO` **im Sync-Skript** | | 5 | **Icons wurden nie vergrößert**: `PIL.thumbnail()` skaliert ausschließlich nach unten, das 277-px-Motiv blieb in 1024er-Icons eine Briefmarke (54 % × 38 % Füllung) | MEDIUM | gelöst mit `resize()` aus dem Original: 81 % | | 6 | **Nur macOS bekam neue Icons** — Windows (`.ico`) und Web (`res/vector-icons/`, `manifest.json`) blieben auf Element | MEDIUM | gelöst, `c51b681` | | 7 | **BookStack-Stack hatte fünf Fehler**: nicht existierende Image-Tags, `healthcheck.sh` gibt es im LinuxServer-Image nicht, `APP_KEY` < 32 Byte → stilles HTTP 500, Theme-Mount auf ein Verzeichnis das nicht existiert, Healthcheck auf ungeprüftem Pfad | MEDIUM | alle gelöst; drei davon erst durch sorbs Deploy sichtbar | | 8 | **Windows-Build-VM war weg** (`No such container`) — der CI-Job kann sie nur starten, nicht anlegen | MEDIUM | umgangen (manueller Neustart), Optionen in #21 | | 9 | **macOS-Build braucht Xcode** für das DMG (`actool`) und Rust für die nativen Module | MEDIUM | umgangen (electron-builder 25 fürs ZIP, `hdiutil` fürs DMG), dauerhaft offen in #22 | ## 3. Was die Eingrenzung ermöglicht hat **Die Traefik-Logs.** Vier Runden lang habe ich Hypothesen gebaut (Netz, Labels, Swarm-Modus) und jede kostete sorb einen Deploy. Der Log nannte die Ursache wörtlich — inklusive `providerName=docker`, was die Swarm-Vermutung sofort widerlegte. **Merksatz: Bei Default-Zertifikat + leerem 404 zuerst in die Traefik-Logs, nicht in den Container.** **Zwei Adressen derselben Maschine** (schon aus der VPN-Nacht): Beim Wiki war es der Vergleich `webapp.asar` vs. `app.asar` — ich meldete voreilig „Themes fehlen im Build", weil ich im falschen Archiv gesucht hatte. **Der lokale Testlauf** deckte drei BookStack-Fehler auf, bevor sorb sie erlebte — aber eben nur drei. Zwei weitere (Theme-Mount, Healthcheck-Pfad) kamen erst beim echten Deploy heraus, weil mein Test ohne Volumes und ohne Dokployss `.env`-Behandlung lief. **Ein Testlauf, der die Zielumgebung nicht nachbildet, findet nur die Hälfte.** ## 4. Lehren 1. **Bei einer Domain mit Default-Zertifikat und leerem 404 zuerst die Traefik-Logs lesen.** Ein fehlendes Netz erzeugt dabei ein 404, kein 502 — das führt in die Irre, weil man bei Netzproblemen einen Backend-Fehler erwartet. 2. **Keine eigenen `traefik.*`-Labels neben denen von Dokploy.** Ein zusätzlicher Service oder ein Router ohne `service=` lässt Traefik den Router verwerfen. 3. **Statische Dateien dürfen nie auf HTML zurückfallen** (`try_files $uri =404`), sonst sieht jeder fehlende Pfad wie ein Erfolg aus. 4. **`thumbnail()` vergrößert nicht.** Wer Icons erzeugt, braucht `resize()` — und die Quelle in voller Auflösung. 5. **Ein Rebrand ist mehr als eine Datei.** Icons leben pro Plattform an eigenen Orten; wer nur eine ersetzt, merkt es erst, wenn der Nutzer fragt. 6. **Testumgebung ≠ Zielumgebung.** Der lokale Docker-Lauf fand die Fehler, die das Image betreffen — nicht die, die aus Dokployss `.env`-Handling und den Volumes entstehen. 7. **Verweise auf Issues prüfen, bevor sie in ein Release wandern.** In den Release-Notes stand ein Link auf ein Issue, das ich nie angelegt hatte (fiel erst bei der Konventionsprüfung auf). ## 4a. Nachtrag (2026-08-02 vormittags): drei weitere Runden **BookStack lief erst nach fünf Anläufen.** Die Ursachen kamen nacheinander und maskierten einander: | # | Ursache | Wie sie sich zeigte | |---|---|---| | 1 | Anführungszeichen im `APP_KEY` (Dokploy schreibt Werte 1:1 in eine `.env`) | Deploy bricht ab: `unterminated quoted value` | | 2 | `BOOKSTACK_TAG=25.07` aus meiner ersten `.env.example` — den Tag gibt es nicht | `manifest unknown` | | 3 | **Healthcheck auf `/login` schlug fehl → Container `unhealthy` → Traefik überspringt ihn komplett** | Default-Zertifikat + leeres 404, **identisch zum Bild eines fehlenden Netzes** | | 4 | `DB_PASSWORD` nachträglich geändert; MariaDB legt Zugangsdaten nur beim ersten Start an | `Access denied for user 'bookstack'` | | 5 | `APP_KEY` weder 32 Byte noch mit `base64:`-Präfix | `Unsupported cipher or incorrect key length` | **Die wichtigste neue Lehre:** Ein **`unhealthy` Container ist für Traefik unsichtbar** — kein Router, kein Service, egal wie korrekt die Labels sind. Das Symptom ist ununterscheidbar von einem fehlenden Netz. Ein Healthcheck, der nicht im laufenden Container verifiziert wurde, ist damit kein Sicherheitsnetz, sondern ein Risiko. Ich hatte ihn zweimal ungeprüft geändert (`/status` → `/login`). **Rebrand:** Der Name saß erst nach drei Anläufen überall. `productName` regelt den App-Namen (macOS/Windows), **`name`** den Linux-Paketnamen, das Binary und den `/opt`-Pfad — und die CI braucht `VARIANT_PATH`, sonst greift die Variante gar nicht. Icons: `PIL.thumbnail()` skaliert **nur nach unten**, weshalb das Motiv in 1024er-Icons nie vergrößert wurde; und ein Rebrand betrifft `.png`, `.ico`, `.icns`, sieben Web-Icons und das Manifest — nicht eine Datei. **Muster über beide Nächte:** Meine teuersten Fehler entstanden nicht durch falsche Analysen, sondern durch **ungeprüfte Änderungen** — ein Healthcheck ohne Test, ein Issue-Verweis ohne Existenzprüfung, ein Icon-Skript ohne Blick aufs Ergebnis. Die Diagnose war jedes Mal gut, sobald echte Daten vorlagen (Traefik-Logs, Laravel-Log, `docker inspect`). ## 5. Offen - **Entscheidung DOC-03 (#20)**: Docusaurus oder BookStack — beide laufen jetzt, der Vergleich kann an echten Inhalten stattfinden. - **Navbar-Logo im Wiki**: HTML, CSS und Bild werden nachweislich korrekt ausgeliefert, im Browser aber nicht sichtbar. Braucht einen Blick in die Entwicklerkonsole. - **macOS reproduzierbar bauen** (#22), **Windows-VM-Robustheit** (#21). - **Rebrand-Rest**: About-Attribution im Client, `brand` in der Prod-Config, Signing (ThreadNet-Web#6) — ohne Signatur bleibt für Nutzer auf macOS der `xattr`-Schritt und auf Windows die SmartScreen-Warnung. ## Nachtrag 2026-08-02 — die Paletten waren erfunden Nachmittags nachgetragen, weil der Befund das Ergebnis oben relativiert. **Was war.** Die zehn Themes aus dem Rollout trugen nicht die Farben aus Anthropics [theme-factory-Skill](https://github.com/anthropics/skills/tree/main/skills/theme-factory), sondern **meine Auslegung ihrer Namen**. Ich hatte den Skill benannt, aber nie seine Farbwerte gelesen. Aufgefallen ist es sorb an „Sunset Boulevard": Er hatte gedämpftes Terrakotta erwartet, bekam Koralle und Pink. Die Prüfung an der Quelle zeigte, dass fast alle zehn danebenlagen — am gröbsten beim Grundcharakter: **sieben der zehn sind hell gemeint, ich hatte sechs dunkel angelegt.** **Warum es nicht auffiel.** Erfundene Farben sehen nicht falsch aus. Ein Theme namens „Ocean Depths" in dunklem Türkis wirkt stimmig — es fällt erst auf, wenn jemand die Vorlage kennt. Anders als ein kaputter Healthcheck erzeugt eine erfundene Palette kein Symptom, auf das man stoßen könnte. **Falle für die nächste Runde.** Ob ein Theme hell oder dunkel gemeint ist, steht in den Skill-Beschreibungen **nicht verlässlich** — „Warm Sand · backgrounds" findet sich bei einem Theme, dessen Showcase-Seite dunkel ist. Belastbar ist nur `theme-showcase.pdf`: Seiten rendern, Hintergrundfarbe messen. Werte und Fallen stehen in [`shared/branding.md`](../wiki/architecture/branding.md). **Bestätigung des Musters aus Abschnitt 4.** Auch das war kein Analysefehler, sondern eine **ungeprüfte Änderung** — dieselbe Wurzel wie Healthcheck, toter Issue-Verweis und Icon-Skript. Nur diesmal ohne Fehlermeldung, die es aufdeckt. Die Lehre schärft sich damit: Es genügt nicht, Ergebnisse zu prüfen — bei Vorlagen ist die **Quelle** zu prüfen, bevor etwas daraus abgeleitet wird. **Nebenbefund.** sorbs von Hand eingestelltes BookStack-Schema und die offizielle Sunset-Boulevard-Palette sind bis auf zwei Ziffern identisch (`#e76e51`/`#e76f51`, `#f3a261`/`#f4a261`) — unabhängig voneinander auf demselben Coolors-Satz gelandet. **Korrigiert:** gitops `b10b607` (Web, live verifiziert) · ThreadNet-Web `80fcf6c` (Desktop-Config). Das BookStack-CSS lag bereits richtig. ⚠️ **Die released Desktop-Binaries tragen weiter die alten Farben** — die Themes stecken in `resources/webapp.asar`. Abgestimmt so belassen; der nächste reguläre Build zieht die Korrektur mit (nachgehalten in ThreadNet-Web#11, `status:wartet`).