# Intent: Automatische Nix-Garbage-Collection und Generationslimit auf blunix/pinix **Status:** Phase 1 (Preflight) abgeschlossen; Phase 2 auf blunix umgesetzt, verifiziert und deployed (2026-09-05, Commit 5cd83cf). Für pinix bleibt Phase 2 im Repo (deklarativ, ungetestet vor Ort) vorerst undeployed — der pinix-Dry-Run deckte einen davon unabhängigen, großen Rückstand gegenüber `dev` auf (praktisch der gesamte Dienstkatalog würde neu starten), der erst separat geklärt werden soll, bevor dort überhaupt geswitcht wird. Phase 3 weiterhin offen. **Datum:** 2026-09-02 (Preflight-Ergebnisse ergänzt, Phase 2 deployed 2026-09-05) ## Ziel Automatische, wiederkehrende Nix-Garbage-Collection und eine Begrenzung der Boot-Menü-Generationen auf `blunix` und `pinix` einführen, damit alte Store-Generationen und Boot-Einträge nicht mehr unbegrenzt wachsen. Beobachtung, die diesen Auftrag ausgelöst hat: Am 2026-09-02 wurden auf blunix 45 alte Systemgenerationen sowie 100% Diskauslastung und ein gescheiterter `nix flake check`/Build festgestellt; der genaue ursächliche Zusammenhang zwischen Generationenzahl und Vollauslastung ist nicht im Detail (Store-Belegung, größte GC-Roots) dokumentiert und wird in Phase 1 nachgeholt. Zusätzlich die aktuelle Diskvoll-Situation auf blunix beheben — aber als eigener, separat freizugebender operativer Schritt, nicht als Nebeneffekt der deklarativen Änderung. ## Umfang Dreiphasiger Ablauf, jede Phase mit eigenem Abschluss: **Phase 1 — Preflight (read-only, beide Hosts):** - `df -B1 /` und `df -B1 /boot` auf blunix und pinix. - Auflistung vorhandener Systemgenerationen und GC-Roots (`nix-env --list-generations -p /nix/var/nix/profiles/system`, `nix-store --gc --print-roots` o. ä.). - Store-Belegung und größte GC-Roots dokumentieren, um die eingangs genannte Beobachtung zu erhärten oder zu widerlegen. - Anhand der gemessenen Werte konkrete `min-free`/`max-free`-Schwellen je Host festlegen (siehe Annahmen). **Phase 2 — Deklarative Konfiguration (blunix, pinix):** - `nix.gc.automatic` mit wöchentlicher GC, `--delete-older-than 30d`. - `nix.settings.min-free`/`max-free`, Werte pro Host konfigurierbar (nicht zwingend identisch — pinix' SD-Karte hat andere Kennzahlen als blunix' VPS-Platte); konkrete Bytes aus Phase 1. - `boot.loader..configurationLimit = 10` auf beiden Hosts (blunix: grub, pinix: generic-extlinux-compatible). - Gemeinsame Werte über ein eigenständiges Modul, das **nur** in `hosts/blunix/localServices/default.nix` und `hosts/pinix/localServices/default.nix` importiert wird — ausdrücklich nicht über `hosts/globalServices/default.nix`, da dieses auch von `tnix` importiert wird und `tnix` von diesem Auftrag ausgeschlossen bleibt. - Build und `nix flake check` für beide Hostkonfigurationen als Abschluss dieser Phase. **Phase 3 — Cleanup auf blunix (destruktiv, eigene Freigabe erforderlich):** - Erst nach Phase 1 und 2 sowie einer gesonderten, ausdrücklichen Ausführungsfreigabe durch den Nutzer. - Altersbegrenzter Cleanup (`--delete-older-than 30d`, dieselbe Frist wie in Phase 2), ausdrücklich **nicht** `nix-collect-garbage -d` ohne Altersgrenze. - Vorher: bekannte gute Generation identifizieren und bestätigen, dass sie die 30-Tage-Frist übersteht. - Nachher: Diskbelegung und verbliebene Generationen erneut prüfen. ## Phase-1-Ergebnisse (Preflight, 2026-09-05) **blunix:** - `/`: 39,5 GB gesamt, ~184–192 MB frei (100%); `/boot` (eigene Partition, 524 MB) unkritisch (12% belegt). - Nur noch 4 Systemgenerationen (364–367, alle vom 04./05.09.) — nicht die 45 vom 02.09., offenbar zwischenzeitlich schon aufgeräumt. - Die drei alten Generationen zu löschen würde nur ~22 MB freigeben (fast identischer Closure wie die aktuelle). - Reines `nix-collect-garbage` (ohne Generationen zu löschen): ~810 MB reclaimable (26.074 tote Pfade, überwiegend klein). - Store insgesamt: 29 GB, kein einzelner Ausreißer (breite Masse an Paketen: Codex 539 MB, MariaDB 272 MB, Claude Code 215 MB, WordPress-HdM 196 MB, Traefik 185 MB, drawio 146 MB, …). `/var` zusätzlich 4,4 GB (davon 424 MB WordPress-Backup, 527 MB Logs). - **Die eingangs vermutete Kausalität (viele alte Generationen → Vollauslastung) ist für den aktuellen Zustand widerlegt**: es sind kaum noch alte Generationen da, und selbst volles GC bringt nur ~800 MB. Der Store ist schlicht legitim groß (29 GB) für eine 37-GB-Platte — automatische GC/Boot-Limits bremsen das Nachwachsen, lösen aber die strukturelle Platzknappheit allein nicht. **pinix:** - `/`: 118 GB gesamt, 49 GB frei (57%) — unkritisch, wie in den Annahmen vermutet. - 227 Systemgenerationen, älteste vom 06.07.2025 — hier liegt die eigentliche Altlast. 21 Boot-Menüeinträge (extlinux). - Reines GC: ~873 MB reclaimable (12.184 tote Pfade). Store: 38 GB. - Hier umgekehrtes Bild: kein akuter Platzdruck, aber reale Generationen-Anhäufung, die ohne `configurationLimit`/GC nur weiterwächst. **Daraus abgeleitete Schwellen (ersetzen die vorherige offene Annahme unten):** - blunix: `min-free` 1 GB, `max-free` 3 GB — realistisch angesichts der knappen Reserven; löst die 100%-Auslastung selbst nicht, das braucht eher Phase 3 plus ggf. eine separate, spätere Entscheidung (Disk vergrößern? `/var/backups` aufräumen?) außerhalb dieses Auftrags. - pinix: `min-free` 2 GB, `max-free` 6 GB — bewusst zurückhaltender wegen SD-Karten-Schreibverschleiß bei nur wöchentlichem GC. ## Explizit ausgeschlossen - `tnix` bleibt außen vor (Laptop, manuell verwaltet, kann ausgeschaltet bleiben) — auch nicht indirekt über ein gemeinsames Modul in `globalServices/`. - Phase 3 (Cleanup) läuft nicht automatisch im selben Zug wie Phase 2; keine implizite Freigabe durch dieses Dokument. ## Annahmen - Pinix hat aktuell kein akut geprüftes Diskproblem; Phase 1 klärt das für beide Hosts gleichermaßen, statt es zu unterstellen oder auszuschließen. - Rückhaltedauer (30 Tage) und Boot-Generationenlimit (10) sind bewusst jetzt schon fest gewählt, weil sie unabhängig von der absoluten Plattengröße sinnvolle Standardwerte sind (Rollback-Fenster vs. Store-Wachstum). - Die konkreten `min-free`/`max-free`-Bytes-Schwellen sind jetzt anhand der Phase-1-Messung festgelegt, siehe „Phase-1-Ergebnisse" oben: blunix 1 GB/3 GB, pinix 2 GB/6 GB. ## Offene Risiken - Laut Phase-1-Messung reicht 30 Tage Rückhaltedauer auf blunix allein nicht, um die 100%-Auslastung zu beheben (reines GC bringt dort nur ~800 MB) — das ist kein Bug in der Konfiguration, sondern eine Grenze dieses Auftrags: Phase 2 bremst weiteres Wachstum, löst aber nicht die bestehende Knappheit. Auf pinix ist 30 Tage bei 49 GB frei unkritisch. - Falls pinix' SD-Karte empfindlich auf häufige Schreibzugriffe reagiert, kann ein für blunix passender GC-Zeitplan für pinix zu aggressiv sein — in Phase 1 gegenprüfen. ## Erfolgskriterien - Phase 1: Preflight-Werte für beide Hosts dokumentiert, `min-free`/ `max-free`-Schwellen je Host festgelegt. - Phase 2: `nix flake check` und Build beider Hostkonfigurationen erfolgreich; nach Aktivierung: `nix-gc`-Timer läuft, effektive `min-free`/`max-free`-Werte stimmen mit der Konfiguration überein, Anzahl Boot-Menüeinträge ≤ 10. - Phase 3: Diskauslastung auf blunix nach Cleanup deutlich unter 100%; die zuvor bestätigte gute Generation ist weiterhin vorhanden; ein erneuter Build/`nix flake check` scheitert nicht mehr an Diskplatzmangel.