Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QYZodsX5a4ksWdrwKXSExX
151 lines
7.4 KiB
Markdown
151 lines
7.4 KiB
Markdown
# 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.<bootloader>.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.
|