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>
276 lines
14 KiB
Markdown
276 lines
14 KiB
Markdown
# 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](docs/repo-split-inventar.md)).
|
|
- **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:
|
|
|
|
```text
|
|
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`](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
|
|
|
|
```text
|
|
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.
|