# pinix auf Minimalbetrieb reduziert (12.09.2026) Für den Aufbau von Traefik als IPv6-Eingang auf pinix ([Intent](intent/pinix-ipv6-traefik-webserver.md)) wurden alle nicht benötigten Dienste in `hosts/pinix/localServices/default.nix` auskommentiert. Ziel: kurze Rebuild-/Deploy-Zyklen und freie Ports 80/443. Zu diesem Zeitpunkt aktiv blieben nur `tailscale.nix` (Fernzugang und Rückweg), `secrets.nix`, `packages.nix` und `nix-gc.nix`. Closure: **6,74 GiB → 4,29 GiB**, 282 Store-Einträge entfernt. Zu diesem Zeitpunkt gestoppt wurden: dashboard, desk, files, finance-agent-worker, finance-xmpp-listener, forgejo-dump, gotosocial, icecast-radio, liquidsoap-radio, nginx, phanpy, postgresql, prosody, radicale, restic-backups-pinixBackup, samba (smbd/nmbd/winbindd), webdav, webhook, website. forgejo und prosody laufen ohnehin auf blunix — am 12.09.2026 geprüft: dort zwei aktive XMPP-Sessions, auf pinix null. Die pinix-Instanzen waren Altbestand. ## Weiterentwicklung seit dem Minimalbetrieb Der damalige Minimalzustand war ein Zwischenstand für den IPv6-/Traefik-Test. Seitdem sind BIND, Unbound, LLDAP und ACME wieder aktiv. Der parallele Dex-/Headscale-Stack wurde am 13.09.2026 aktiviert; der Stand ist in [`pinix-identity-stack.md`](pinix-identity-stack.md) dokumentiert. Die Aussagen oben zu „nur“ aktiven Diensten und der gestoppten Eingangsschicht sind deshalb als historischer Stand vom 12.09.2026 zu lesen. ## Keine Daten gelöscht Alles unter `/var/lib` bleibt unberührt. Reaktivierung ist das Wiedereinkommentieren der jeweiligen Zeile in `default.nix`. ## Fallstrick beim Reaktivieren: UIDs/GIDs Die Aktivierung entfernt die Dienstnutzer. NixOS vergibt dynamisch zugeteilte IDs beim Neuanlegen nicht garantiert wieder gleich; die Dateien in `/var/lib` behalten aber ihre numerischen Eigentümer. Ein reaktivierter Dienst kann dann seine eigenen Daten nicht mehr lesen. Betroffen sind die dynamisch vergebenen IDs (900er-Bereich). `postgres`, `nginx`, `prosody` und `webdav` haben feste NixOS-IDs und sind unkritisch. Stand vor der Reduktion: ``` # user:uid:gid postgres 71 71 (fest) nginx 60 60 (fest) prosody 149 149 (fest) webdav 322 322 (fest) radicale 995 991 dynamisch forgejo 994 990 dynamisch gotosocial 992 988 dynamisch smbwebdav 990 986 dynamisch icecast-radio 989 985 dynamisch # gruppen prosody:149 (Mitglied: nginx) smbwebdav:986 (Mitglied: webdav) radicale:991 forgejo:990 gotosocial:988 icecast-radio:985 ``` Gegenprobe nach dem Reaktivieren: `ls -n /var/lib/` und die IDs mit der Tabelle vergleichen. Bei Abweichung entweder die ID über `users.users..uid` festnageln oder den Datenbestand umchownen. ## Secrets `hosts/pinix/localServices/secrets.nix` verwies auf Nutzer/Gruppen, die es ohne die Dienste nicht mehr gibt (`prosody`, `icecast-radio`, Gruppe `radicale`). Diese Einträge sind auskommentiert bzw. auf root gesetzt, sonst scheitert die Aktivierung beim `chown` — dasselbe Muster, das die Datei oben schon für `oidcHeadscale` und `traefik` dokumentiert. ## Rückbau Zeilen in `hosts/pinix/localServices/default.nix` und die zugehörigen Blöcke in `secrets.nix` wieder einkommentieren, neu bauen, deployen. ## Warum das Reduzieren den Bauweg verkürzt Der eigentliche Gewinn ist nicht nur die kleinere Closure, sondern dass pinix jetzt **selbst** bauen kann, schnell genug für echte Iteration. Weil die Konfiguration deklarativ ist, kostet das Zusammenstreichen nichts: kein Datenverlust, Rückbau ist ein Wiedereinkommentieren. Damit entfällt für den Alltag der Umweg über nixbuild.net — eine externe Abhängigkeit weniger im Arbeitszyklus. Gemessen am 12.09.2026 auf dem reduzierten System: | Schritt | Dauer | | --- | --- | | `rsync` des Arbeitsbaums nach pinix | 1,5 s | | `nixos-rebuild switch`, warm | 41 s | | `nixos-rebuild switch`, kalter Eval-Cache | 2:45 | ```bash rsync -a --delete --exclude .git ./ pinix:/home/drone/nixos-config-build/ ssh pinix 'cd /home/drone/nixos-config-build && \ sudo nixos-rebuild switch --flake path:.#pinix --no-reexec' ``` `--no-reexec` ist zwingend: sonst versucht `nixos-rebuild`, sich selbst über `` via `NIX_PATH` neu zu bauen, was auf diesem reinen Flake-System nicht eingerichtet ist. Kein Commit und kein Push nötig — der Arbeitsbaum wird direkt übertragen. ## Voraussetzung: DNS64 auf pinix Der erste lokale `nixos-rebuild` scheiterte daran, dass pinix `https://github.com/NixOS/nixos-hardware/...` nicht laden konnte („Timeout was reached (28) after 15002 milliseconds"). Ursache war nicht der Build, sondern das Netz: pinix fragte über Tailscale den AdGuard auf blunix, bekam für den IPv4-only-Host github.com keine synthetische AAAA und fiel auf die IPv4-Default-Route zurück — die hinter dem Nokia still verworfen wird. Behoben in `hosts/pinix/configuration.nix` und `localServices/tailscale.nix`, gleiches Muster wie auf tnix (`docs/ipv6-uplink-tnix-mango.md`): - `--accept-dns=false`, damit der DNS64-Resolver des Mango greift - `nooption routers` für `end0`, damit die tote IPv4-Default-Route gar nicht erst gesetzt wird (`wlan0` bleibt unberührt) - `networking.hosts` aus `config.tailnetIPs` als Ersatz für MagicDNS Danach: `github.com` → HTTP 200 über `64:ff9b::8c52:7903` in 0,7 s. SSH von tnix ist davon unabhängig und war nie das Problem — Tailscale verbindet die beiden im selben LAN direkt (`via 192.168.8.244:41641 in 2 ms`), nicht über ein DERP-Relay. ## Erledigt: pinix kann wieder von Forgejo fetchen Der Recovery-Checkout `/home/drone/nixos-config` auf pinix hing auf `248151e` fest, `git fetch` scheiterte mit „Host key verification failed": Forgejos SSH lauscht auf **Port 2222** und ist ein Go-Server mit eigenem `ssh-rsa`-Hostkey, in `~drone/.ssh/known_hosts` gab es aber nur Einträge für Port 22 (`100.64.0.1` und `blunix`, beide ed25519). Der Eintrag `[100.64.0.1]:2222` fehlte. Gepinnt wird er seit `355b42e` deklarativ in `hosts/globalServices/forgejo-known-host.nix` — global, weil es eine Client- und keine Server-Eigenschaft ist: auf pinix verschwand der alte Pin zusammen mit dem auskommentierten `localServices/forgejo.nix`. Der Pin allein reicht aber nicht, denn er ist selbst Teil des Repos: pinix bräuchte den Commit, um fetchen zu können, und müsste fetchen, um ihn zu bekommen. Der Ausweg ist der `rsync`-Bauweg von oben, der ohne git auskommt — Quelle von tnix übertragen, lokal bauen, switchen. Der Build umfasste am 12.09.2026 vier Derivationen, davon eine echte (`etc-ssh-ssh_known_hosts`); `diff-closures` gegen die laufende Generation war leer. Danach `git fetch origin` erfolgreich, Checkout per `--ff-only` auf `355b42e` nachgezogen. Nicht mit abgeschaltetem StrictHostKeyChecking umgehen (siehe CLAUDE.md) — der Fingerprint gehört verifiziert und gepinnt, so wie hier geschehen.