This repository has been archived on 2026-09-17. You can view files and clone it, but you cannot make any changes to its state, such as pushing and creating new issues, pull requests or comments.
nixos-config/Plan.md
pijukka ef9d2a1a2b Archive nixos-config after the per-host repo split
tnix, pinix and blunix now build and deploy from their own repositories.
This is the last commit here; the repository is archived on Forgejo and
mirrored to pinix's cgit. See Plan.md and docs/repo-split-inventar.md.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17 13:30:29 +02:00

14 KiB

Plan: nixos-config in drei eigenständige Repositories aufteilen

Stand: 17.09.2026 — Entscheidungen aus der Plan-Review eingearbeitet.

Ausgangslage

Alle drei Maschinen (tnix, pinix, blunix) werden aktuell über ein gemeinsames Repository nixos-config verwaltet (1750 Commits, ein Flake, gemeinsame globalServices/, eine secrets/secrets.nix für alle Hosts).

Ziel sind drei eigenständige Repositories, deren Grenzen der Rolle der jeweiligen Maschine folgen. Hostnamen bleiben unverändert.

Repo Host Rolle
tnix tnix persönliche Maschine (Laptop)
pinix pinix persönliche, autonome Server-Infrastruktur
blunix blunix gemeinsam nutzbare Plattform (0ff.space)

Rollen

tnix

  • persönlich, lokal, die eigentliche Arbeitsmaschine
  • Konfiguration betrifft primär die eigene Arbeitsumgebung (inkl. home-manager)

pinix

  • Raspberry Pi 4 (aarch64), persönlicher autonomer Server
  • IPv6, soll möglichst unabhängig funktionieren
  • hostet persönliche Dienste und Tools
  • cgit als persönlicher Git-Server (nur im pinix-Tailnet)
  • eigener Identity-Stack (Dex + LLDAP + Headscale unter domain2)
  • Headscale ist das Admin-Tailnet: alle drei Hosts sind Mitglied (Stand seit 14.09.2026, bleibt so)
  • Uplink: pinix hat die Funktionen des (offline genommenen) Mango-Routers übernommen
  • lukasrosier.com gehört hierher und läuft auf pinix, IPv6-only (bisher bewusst auf blunix — Umzug ist Teil der Aufteilung; kein IPv4-Proxy über blunix)

blunix

  • VPS, bleibt dauerhaft als gemeinsame Plattform (Roadmap-Punkt „VPS durch IPv6 ersetzen" damit erledigt/umformulieren)
  • Dienste, die mit anderen Menschen geteilt werden, über 0ff.space: Launcher/Startseite, Prosody/XMPP, xmpp-web, Forgejo, künftige Kommunikationsdienste
  • eigener Identity-Stack (Dex + LLDAP + Headscale für 0ff.space); der blunix-Headscale ist nur für geteilte Nutzer, nicht für die Admin- Verbindung zwischen den eigenen Hosts
  • Forgejo als Git-Server

Git: Source of Truth und Clones

Jedes Repo hat sein Origin auf „seinem" System; auf den anderen Systemen liegen Clones. Bearbeitung ist überall möglich: direkt auf dem Host, oder auf tnix lokal bzw. agentisch per SSH, mit Remote-Build auf dem Zielhost. Maßgeblich ist immer das versionierte Origin.

Repo Origin (Source of Truth) Clones / Mirror
tnix ~/tnix auf tnix Mirror auf pinix/cgit
pinix pinix/cgit Clone auf tnix
blunix blunix/Forgejo Clone auf tnix
ereader-viewer pinix/cgit Flake-Input des pinix-Repos
website pinix/cgit (bisher Forgejo) Auto-Pull auf pinix
memory pinix/cgit (aus memory/) Clone auf tnix
nixos-config Archiv, read-only im Backup

Entscheidungen

  1. Gemeinsame Module werden kopiert, kein viertes common-Repo. globalServices/ (sshd, security, zsh, journald, packages, …) landet als Kopie in jedem Repo und darf pro Rolle auseinanderlaufen. Ebenso bekommt jedes Repo sein eigenes variables.nix/variables-local.nix mit nur den dort gebrauchten Optionen.
  2. Git-Historie: frischer Start. Die neuen Repos beginnen mit einem Initial-Commit. nixos-config wird vorher mit dem vollständigen aktuellen Stand committet und danach read-only archiviert.
  3. Secrets pro Repo. Jedes Repo bekommt eine eigene secrets/secrets.nix mit nur den eigenen Host-Keys als Empfänger; betroffene .age-Dateien werden kopiert und per agenix -r neu verschlüsselt. Geteilte Secrets (z. B. dns-challenge, domain, mailPW) werden pro Repo dupliziert — wo sinnvoll, später getrennt rotiert.
  4. Build-unabhängig, nicht laufzeit-unabhängig. Jedes Repo baut ohne die anderen. Zur Laufzeit bleiben bewusste Kopplungen (siehe unten), die als Werte in variables.nix statt als Cross-Repo-Importe abgebildet werden.
  5. Agents (agent-codex, board-agent, orga-agent, agents/) werden ins blunix-Repo übernommen, aber nicht importiert (deaktiviert). Über Reaktivierung und Repo-Zugriff wird später entschieden.
  6. GoToSocial läuft aktuell nirgends und ist nicht Teil der Aufteilung — kommt danach als eigener Schritt ins blunix-Repo.
  7. ereaderViewer (path:/home/builder/ereader/viewer) wird ein eigenes Repo auf pinix/cgit und per Git-URL als Flake-Input eingebunden.

Bekannte Laufzeit-Kopplungen

  • Admin-Tailnet: blunix und tnix hängen am pinix-Headscale. Fällt pinix aus, ist blunix nur noch öffentlich per SSH erreichbar.
  • Traefik auf blunix → pinix-Backends: keine mehr aktiv — alle Routen dorthin sind tot und werden auskommentiert übernommen (Inventar).
  • Forgejo-Hostkey auf allen Hosts; pinix kann das blunix-Repo im Notfall klonen. SSH blunix → pinix (nixbuild.nix) entfällt.
  • tnix-Backup-Skripte ziehen per rsync von pinix und blunix.
  • lukasrosier.com auf pinix: bewusst IPv6-only, keine Kopplung an blunix.

Backup

Zentraler Ordner, als Ganzes auf einen USB-Stick kopierbar, unabhängig von der Erreichbarkeit von pinix oder blunix:

nixos-backup/
├── tnix.bundle
├── pinix.bundle
├── blunix.bundle
├── ereader-viewer.bundle
├── website.bundle
├── memory.bundle
└── nixos-config.bundle      # Archiv

Umfang: nur die Git-Repos, vollständig mit allen Branches (git bundle create … --all oder git clone --mirror). Nicht enthalten: Flake-Inputs für Offline-Rebuilds, private Keys zum Entschlüsseln der Secrets, Dienst-Daten (die sichert weiterhin restic).

Vorgehensweise

  1. Laufenden Stand sichern: uncommittete Änderungen (live-intent, ereader-viewer, tailnet-dns, tnix-Configs, docs, …) in nixos-config committen und pushen.
  2. Inventar erstellen (docs/repo-split-inventar.md): jedes Modul, jeder Service, jedes Secret, jedes Skript, jede Datei unter docs/, services/, scripts/, home/, agents/ → Zuordnung tnix / pinix / blunix / kopieren / Archiv; dazu alle Cross-Host-Referenzen (tailnetIPs.*, Traefik-Routen, Webhooks, known_hosts, nixbuild).
  3. Neue Repos auf cgit: ereader-viewer (Flake-Input umstellen), website (von Forgejo umziehen, inkl. scripts/resize-image.sh), memory (aus memory/). — Erledigt 17.09.2026: alle drei unter /var/lib/git angelegt; ereader-viewer frisch importiert und als git+file-Input eingebunden (pinix-Switch ergab dasselbe System); website als Mirror aller Branches, Forgejo-Kopie bleibt bis Schritt 5 parallel und synchron (Auto-Pull auf blunix); memory per git subtree split.
  4. tnix als Pilot: Repo aufbauen, Muster für kopierte globalServices, variables.nix und secrets.nix festlegen. Rebuild auf tnix, Origin unter ~/tnix, Mirror auf cgit. — Erledigt 17.09.2026 (~/tnix @ 0d77a25). Festgelegtes Muster für pinix/blunix:
    • flaches Layout ohne hosts/<name>/: configuration.nix, globalServices/ (nur tatsächlich importierte Kopien, ohne secretFiles.nix), localServices/, user/, secrets/, tests/
    • variables.nix nur mit den Optionen, die das Repo liest
    • secrets/secrets.nix nur mit eigenen Keys, .age-Dateien per agenix -r neu verschlüsselt, Inhalte per agenix -d gegengeprüft
    • flake.lock aus nixos-config übernehmen, damit nixpkgs-Revisionen gleich bleiben; vor dem Switch diff-closures gegen das laufende System (Pilot-Check)
    • Mirror: Bare-Repo auf cgit + post-commit-Hook (git push --mirror) Ergebnis-Diff tnix: nur 15 ungenutzte Secrets weg, fastpi aus /etc/hosts, wpa-Units mit neuen Restart-Triggern. switch sauber, WLAN/Tailnet/SSH/cgit danach geprüft. tnix wird ab jetzt nur noch aus ~/tnix deployt; hosts/tnix hier ist eingefroren.
  5. pinix: Repo aufbauen, lukasrosier.com von blunix übernehmen (Auto-Pull-Hook für das website-Repo). Website-Bilder aus /var/www/website-data (von blunix kopiert am 17.09.) mit Verzeichnis-Listing ausliefern, data.0ff.space-URLs im website-Repo umstellen, Default-Ziel von scripts/resize-image.sh anpassen; danach Nachzügler von blunix per rsync abgleichen. — Erledigt 17.09.2026 bis auf den letzten DNS-Schritt (Repo pinix @ e9cf08b auf cgit, Arbeitskopie ~/pinix auf tnix, Build-Verzeichnis pinix:/home/drone/pinix-build):
    • pinix läuft aus dem neuen Repo; diff-closures vorher zeigte nur erwartete Änderungen. Headscale scheiterte beim Switch einmal am gleichzeitigen Traefik-Neustart (OIDC-Discovery EOF) und lief beim automatischen Restart; danach running, keine failed Units.
    • Dex/Headscale-Client-Secret neu generiert (nicht mehr mit blunix geteilt), gegen Dex' Token-Endpunkt geprüft (richtig 400, falsch 401).
    • Website: website.nix mit post-receive-Hook in website.git (Branch dev, der auch auf blunix live war); Bilder unter /pictures/ und /booklet.pdf aus /var/www/website-data. Im website-Repo URLs relativ gemacht (df5f230); alle 26 verlinkten Dateien 200, von blunix aus über pinix' öffentliches IPv6 mit gültigem Zertifikat getestet. Forgejo-Kopie von website ist ab hier veraltet (Archiv in Schritt 7).
    • DNS: Cloudflare-Proxy bleibt (Entscheidung 17.09.). Apex hat MX/NS/TXT, daher proxied AAAA statt CNAME für lukasrosier.com und www, gepflegt von wan-dns-update (folgt der NAT66-Adresse).
    • Offen: die alten A-Einträge (23.88.33.137, blunix) für lukasrosier.com und www löschen. Solange sie existieren, bevorzugt Cloudflare blunix als Ursprung — Besucher sehen noch die alte Kopie mit data.0ff.space-Bildern (funktioniert). Nach dem Löschen data.-Kopie der Bilder erst in Schritt 6 entfernen.
    • Altes .git der Website-Checkout auf pinix liegt unter /home/drone/website-checkout-git.bak-20260917.
    • Nachtrag 17.09.2026: A-Einträge gelöscht (auf ausdrückliche Anweisung). Über IPv4 (Cloudflare) und IPv6 liefert jetzt pinix aus (version.json = df5f230, Bilder 200). Rebuild lokal auf pinix (rsync-Zyklus). Origin auf cgit, Clone auf tnix.
  6. blunix (zuletzt, vorsichtig — Aussperr-Risiko): Repo aufbauen, Website und Agents entfernen bzw. deaktivieren, Traefik-Routen auf pinix-Backends bereinigen. Rebuild auf blunix. Origin auf Forgejo, Clone auf tnix. — Erledigt 17.09.2026 (lukas/blunix auf Forgejo, privat per Push-to-Create, @ fd4c876; Checkout /home/drone/blunix, Clone ~/blunix auf tnix):
    • Agents, orga-Dienste, tasks, graphify-refresh, oauth2-proxy, website-production und nixbuild.nix sind aus; tote Routen, Dex-Clients, AdGuard-Rewrites und die pinix-IP in Forgejos Webhook-Allowlist auskommentiert. Closure ~1 GB kleiner (Chromium, numpy & Co. hingen an den Agents).
    • Aussperr-Check vor dem Switch: sshd, Firewall, Netz, tailscaled unverändert (nur SSH-Client-Config/known_hosts durch nixbuild.nix). hosts/blunix/localServices/sshd.nix war nie importiert (lauscht auf alten 100.64-Adressen) — Archiv.
    • Korrektur zum Inventar: bindPW.age wird auf blunix gelesen (Prosody-Include /run/agenix/0ff.space.cfg.lua), ist mitgenommen.
    • Headscale scheiterte beim Switch wie auf pinix einmal an der gleichzeitig neu startenden Dex/Traefik-Kette und lief beim Restart. Danach running, keine failed Units; öffentlich geprüft: 0ff.space, git., dex., lldap., head., data., hdm., upload., XMPP 5222/5269, intern schema..
    • Befund pinix (offen): Seit dem pinix-Switch um 13:08 hatte der technische Node pinix-dns (tailscaled-pinix) keine Control-Verbindung mehr (PollNetMap gegen 127.0.0.1:443), der Datenpfad zu cgit lief weiter. systemctl restart tailscaled-pinix hat es behoben. Der Prozess sieht trotz BindReadOnlyPaths die Host-/etc/hosts (dex./head. → 127.0.0.1); Mechanismus nicht geklärt. Nach pinix-Switches, die /etc/hosts ändern, prüfen.
    • Die Admin-Sitzung unter /home/drone/nixos-config auf blunix ist unverändert; blunix wird ab jetzt nur noch aus /home/drone/blunix deployt.
    • Die Bilder-Kopie unter blunix:/var/www/data/external/pictures bleibt (Entscheidung 17.09.2026).
  7. nixos-config archivieren (Forgejo: read-only/archiviert), Checkouts unter /home/drone/nixos-config durch die neuen Repos ersetzen. — Erledigt 17.09.2026 (dieser Commit ist der letzte):
    • Alle nixos-config*-Verzeichnisse auf blunix (6, inkl. Wiki-Checkout) und pinix (10) nach /home/drone/archiv-nixos-config-20260917/ verschoben, nicht gelöscht. Uncommittete Stände darin waren alte Zwischenstände (letzter Commit 12.09.), inhaltlich längst in der Historie. Ersetzt durch /home/drone/blunix (Clone) bzw. /home/drone/pinix-build (rsync-Ziel).
    • Archiv-Hinweis oben in README.md, AGENTS.md, CLAUDE.md.
    • Danach: git push --mirror auf pinix-cgit (nixos-config.git), dann nixos-config und website auf Forgejo archiviert.
    • Die Plan-Fortschreibung für Schritt 8 und 9 liegt ab hier in ~/tnix/docs/repo-split/ (tnix ist die Admin-Arbeitsmaschine).
  8. Backup-Skript für nixos-backup/ schreiben und testen: Ordner auf USB kopieren, auf einer anderen Maschine aus den Bundles klonen.
  9. Doku nachziehen: README/CLAUDE.md/AGENTS.md pro Repo, docs/roadmap.md (VPS-Punkt), docs/repos.md.

Weitere Festlegungen

  • LLDAP: Nutzer und Gruppen bleiben so, wie sie aktuell auf den Systemen aktiv sind (blunix-LLDAP für 0ff.space, pinix-LLDAP für domain2) — keine Migration im Zuge der Aufteilung.
  • Doku zu Mango (CLAUDE.md, docs/networking.md u. a.) ist veraltet und wird in Schritt 9 nachgezogen.

Designziel

tnix   = meine persönliche Maschine
pinix  = meine persönliche/private Server-Infrastruktur
blunix = gemeinsam nutzbare Plattform-Infrastruktur

Die technische Struktur — Repo-Grenzen, Git-Hosting, Identität, Secrets — folgt dieser Trennung.