Add SD image pipeline, documentation overhaul, and fix module issues

- Add automatic SD image builds for Raspberry Pi via Forgejo Actions
- Enable binfmt emulation on cryodev-main for aarch64 cross-builds
- Add sd-image.nix module to cryodev-pi configuration
- Create comprehensive docs/ structure with installation guides
- Split installation docs into: first-install (server), reinstall, new-client (Pi)
- Add lib/utils.nix and apps/rebuild from synix
- Fix headplane module for new upstream API (tale/headplane)
- Fix various module issues (mailserver stateVersion, option conflicts)
- Add placeholder secrets.yaml files for both hosts
- Remove old INSTRUCTIONS.md (content moved to docs/)
This commit is contained in:
steffen 2026-03-11 08:41:58 +01:00
parent a5261d8ff0
commit 5ba78886d2
44 changed files with 3570 additions and 609 deletions

View file

@ -0,0 +1,179 @@
# Erstinstallation (x86_64 Server)
Diese Anleitung beschreibt die **manuelle Installation** eines neuen x86_64 Servers (z.B. cryodev-main).
> **Für Raspberry Pi:** Siehe [Neuen Raspberry Pi hinzufügen](new-client.md) - dort wird ein SD-Image automatisch gebaut.
## Übersicht
Bei der Erstinstallation gibt es ein Henne-Ei-Problem:
- SOPS-Secrets werden mit dem SSH-Host-Key verschlüsselt
- Der SSH-Host-Key wird erst bei der Installation generiert
- Daher: Erst installieren, dann Secrets konfigurieren
## Voraussetzungen
- Bootbares NixOS ISO ([Minimal ISO](https://nixos.org/download/#nixos-iso))
- Netzwerkverbindung
- Host-Konfiguration in `hosts/<hostname>/` (ohne secrets.yaml)
## Schritt 1: Host-Konfiguration vorbereiten
### 1.1 Template kopieren
```bash
cp -r templates/generic-server hosts/neuer-server
```
### 1.2 Hostname setzen
`hosts/neuer-server/networking.nix`:
```nix
{
networking.hostName = "neuer-server";
}
```
### 1.3 In flake.nix registrieren
```nix
nixosConfigurations = {
neuer-server = mkNixosConfiguration "x86_64-linux" [ ./hosts/neuer-server ];
};
```
### 1.4 Placeholder secrets.yaml erstellen
```bash
touch hosts/neuer-server/secrets.yaml
```
### 1.5 SOPS-Secrets temporär deaktivieren
In `hosts/neuer-server/default.nix` alle `sops.secrets.*` Referenzen auskommentieren oder mit `lib.mkIf false` umgeben, bis die echten Secrets existieren.
## Schritt 2: Zielmaschine vorbereiten
### 2.1 NixOS ISO booten
Von USB/CD booten.
### 2.2 Root-Passwort setzen (für SSH)
```bash
passwd
```
### 2.3 IP-Adresse ermitteln
```bash
ip a
```
### 2.4 Per SSH verbinden (optional)
```bash
ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no nixos@<IP>
sudo -i
```
## Schritt 3: Installation durchführen
### 3.1 Repository klonen
```bash
nix-shell -p git
git clone <GIT_REPO_URL> /tmp/nixos
cd /tmp/nixos
```
### 3.2 Disk-Konfiguration anpassen
**Wichtig:** Die Disk-ID muss zur Hardware passen!
```bash
# Verfügbare Disks anzeigen
lsblk -o NAME,SIZE,MODEL,SERIAL
ls -la /dev/disk/by-id/
```
In `hosts/neuer-server/disks.sh` oder `disks.nix` die richtige Disk-ID eintragen.
### 3.3 Install-Script ausführen
```bash
bash scripts/install.sh -n neuer-server
```
Das Script:
1. Partitioniert die Disk (via disko oder disks.sh)
2. Generiert hardware.nix (falls nicht vorhanden)
3. Installiert NixOS
### 3.4 Reboot
```bash
umount -Rl /mnt
reboot
```
## Schritt 4: Nach dem ersten Boot
### 4.1 Einloggen
Standard-Passwort: `changeme`
```bash
passwd # Sofort ändern!
```
### 4.2 SSH-Host-Key zu Age-Key konvertieren
```bash
nix-shell -p ssh-to-age --run 'cat /etc/ssh/ssh_host_ed25519_key.pub | ssh-to-age'
```
**Ausgabe notieren!** (z.B. `age1abc123...`)
### 4.3 Auf Entwicklungsrechner: SOPS konfigurieren
`.sops.yaml` bearbeiten:
```yaml
keys:
- &admin_key age1e8p35795htf7twrejyugpzw0qja2v33awcw76y4gp6acnxnkzq0s935t4t
- &neuer_server_key age1abc123... # Key von oben
creation_rules:
- path_regex: hosts/neuer-server/secrets.yaml$
key_groups:
- age:
- *admin_key
- *neuer_server_key
```
### 4.4 Secrets erstellen
```bash
sops hosts/neuer-server/secrets.yaml
```
Mindestens den Tailscale Auth-Key eintragen (siehe nächster Schritt).
### 4.5 SOPS-Referenzen wieder aktivieren
Die in Schritt 1.5 auskommentierten `sops.secrets.*` Referenzen wieder aktivieren.
### 4.6 Konfiguration deployen
```bash
# Lokal bauen und per SSH deployen
nixos-rebuild switch --flake .#neuer-server --target-host root@<IP>
```
## Nächste Schritte
- [Tailscale einrichten](../services/tailscale.md) - VPN-Verbindung
- [Netdata konfigurieren](../services/netdata.md) - Monitoring
- [CD einrichten](../deployment/cd.md) - Automatisches Deployment

View file

@ -0,0 +1,282 @@
# Neuen Raspberry Pi Client hinzufügen
Diese Anleitung beschreibt das Hinzufügen eines **neuen Raspberry Pi Clients** zur Infrastruktur.
## Übersicht: Der Ablauf
```
1. Konfiguration erstellen ──► Template kopieren, anpassen
2. Zur Image-Pipeline hinzufügen ──► Workflow-Matrix erweitern
3. Push auf main ──► Forgejo baut automatisch SD-Image
4. Image flashen & booten ──► SD-Karte beschreiben, Pi starten
5. SOPS konfigurieren ──► Age-Key holen, Secrets erstellen
6. Finales Deployment ──► Tailscale etc. aktivieren
```
## Voraussetzungen
- SSH-Zugang zu cryodev-main (für Tailscale Auth-Key)
- Entwicklungsrechner mit Repository-Zugriff
- SD-Karte (mindestens 8 GB)
---
## Schritt 1: Tailscale Auth-Key generieren
**Auf cryodev-main** (per SSH):
```bash
sudo headscale preauthkeys create --expiration 99y --reusable --user default
```
**Ausgabe notieren!** (z.B. `tskey-preauth-abc123...`)
---
## Schritt 2: Host-Konfiguration erstellen
### 2.1 Template kopieren
```bash
cp -r templates/raspberry-pi hosts/neuer-pi
```
### 2.2 Hostname setzen
`hosts/neuer-pi/networking.nix`:
```nix
{
networking.hostName = "neuer-pi";
}
```
### 2.3 In flake.nix registrieren
```nix
nixosConfigurations = {
# ... bestehende Hosts ...
neuer-pi = mkNixosConfiguration "aarch64-linux" [ ./hosts/neuer-pi ];
};
```
### 2.4 In constants.nix eintragen
```nix
{
hosts = {
# ... bestehende Hosts ...
neuer-pi = {
ip = "100.64.0.X"; # Wird von Headscale vergeben
};
};
}
```
### 2.5 Placeholder secrets.yaml erstellen
```bash
touch hosts/neuer-pi/secrets.yaml
```
### 2.6 SOPS temporär deaktivieren
In `hosts/neuer-pi/default.nix` die `sops.secrets.*` Referenzen auskommentieren, damit das Image ohne Secrets gebaut werden kann.
---
## Schritt 3: Zur Image-Pipeline hinzufügen
Bearbeite `.forgejo/workflows/build-pi-image.yml`:
```yaml
jobs:
build-pi-images:
strategy:
matrix:
# Neuen Host hier hinzufügen:
host: [cryodev-pi, neuer-pi]
```
---
## Schritt 4: Push und Image bauen lassen
```bash
git add .
git commit -m "Add neuer-pi host configuration"
git push
```
Der Forgejo Workflow baut jetzt automatisch ein SD-Image für `neuer-pi`.
**Warten** bis der Workflow fertig ist (30-60 Minuten). Status prüfen unter:
`https://git.cryodev.xyz/steffen/cryodev-server/actions`
---
## Schritt 5: Image flashen
### 5.1 Image herunterladen
Nach erfolgreichem Build unter **Releases**:
```bash
wget https://git.cryodev.xyz/steffen/cryodev-server/releases/latest/download/neuer-pi-sd-image.img.zst
```
### 5.2 Dekomprimieren
```bash
zstd -d neuer-pi-sd-image.img.zst -o neuer-pi.img
```
### 5.3 Auf SD-Karte schreiben
**Achtung:** `/dev/sdX` durch das richtige Gerät ersetzen!
```bash
lsblk # Richtiges Gerät finden
sudo dd if=neuer-pi.img of=/dev/sdX bs=4M conv=fsync status=progress
```
### 5.4 Booten
1. SD-Karte in den Raspberry Pi einlegen
2. Ethernet anschließen
3. Strom anschließen
4. Warten bis gebootet (ca. 2 Minuten)
---
## Schritt 6: SOPS konfigurieren
### 6.1 IP-Adresse finden
Der Pi sollte per DHCP eine IP bekommen. Prüfe deinen Router oder scanne das Netzwerk:
```bash
nmap -sn 192.168.1.0/24 | grep -B2 "Raspberry"
```
### 6.2 SSH verbinden
```bash
ssh steffen@<IP> # oder der konfigurierte User
```
Standard-Passwort siehe `hosts/neuer-pi/users.nix`.
### 6.3 Age-Key ermitteln
Auf dem Pi:
```bash
nix-shell -p ssh-to-age --run 'cat /etc/ssh/ssh_host_ed25519_key.pub | ssh-to-age'
```
**Ausgabe notieren!** (z.B. `age1xyz...`)
### 6.4 .sops.yaml aktualisieren
Auf dem Entwicklungsrechner:
```yaml
keys:
- &admin_key age1e8p35795htf7twrejyugpzw0qja2v33awcw76y4gp6acnxnkzq0s935t4t
- &neuer_pi_key age1xyz... # Der neue Key
creation_rules:
# ... bestehende Regeln ...
- path_regex: hosts/neuer-pi/secrets.yaml$
key_groups:
- age:
- *admin_key
- *neuer_pi_key
```
### 6.5 Secrets erstellen
```bash
sops hosts/neuer-pi/secrets.yaml
```
Inhalt:
```yaml
tailscale:
auth-key: "tskey-preauth-abc123..." # Key aus Schritt 1
netdata:
stream:
child-uuid: "..." # uuidgen
```
### 6.6 SOPS-Referenzen aktivieren
Die in Schritt 2.6 auskommentierten `sops.secrets.*` Referenzen wieder aktivieren.
---
## Schritt 7: Finales Deployment
```bash
git add .
git commit -m "Configure SOPS secrets for neuer-pi"
git push
```
Da Comin auf dem Pi läuft, wird er die neue Konfiguration automatisch pullen.
Alternativ manuell:
```bash
nixos-rebuild switch --flake .#neuer-pi --target-host root@<IP>
```
---
## Schritt 8: Verifizieren
### Tailscale-Verbindung
```bash
# Auf dem Pi
tailscale status
# Auf cryodev-main
sudo headscale nodes list
```
### Netdata-Streaming
Prüfe ob der neue Client im Netdata-Dashboard erscheint:
`https://netdata.cryodev.xyz`
---
## Checkliste
- [ ] Tailscale Auth-Key auf cryodev-main generiert
- [ ] Host-Konfiguration erstellt (Template, flake.nix, constants.nix)
- [ ] Host zur Workflow-Matrix hinzugefügt
- [ ] Gepusht und auf Image-Build gewartet
- [ ] SD-Karte geflasht und Pi gebootet
- [ ] Age-Key ermittelt und in .sops.yaml eingetragen
- [ ] secrets.yaml erstellt (Tailscale-Key, Netdata-UUID)
- [ ] SOPS-Referenzen aktiviert und deployed
- [ ] Tailscale-Verbindung funktioniert
- [ ] Netdata-Streaming funktioniert

View file

@ -0,0 +1,63 @@
# Prerequisites
## Required Tools
Ensure you have the following tools installed on your local machine:
| Tool | Purpose |
|------|---------|
| `nix` | Package manager with flakes enabled |
| `sops` | Secret encryption/decryption |
| `age` | Encryption backend for sops |
| `ssh` | Remote access |
### Installing Nix
Follow the [official Nix installation guide](https://nixos.org/download/).
Enable flakes by adding to `~/.config/nix/nix.conf`:
```
experimental-features = nix-command flakes
```
### Installing Other Tools
With Nix:
```bash
nix-shell -p sops age
```
Or install globally via home-manager or system configuration.
## Repository Access
Clone the repository:
```bash
git clone https://git.cryodev.xyz/steffen/cryodev-server.git
cd cryodev-server
```
## Development Shell
Enter the development shell with all required tools:
```bash
nix develop
```
## Verifying Setup
Check that the flake is valid:
```bash
nix flake check
```
Build a host configuration (dry run):
```bash
nix build .#nixosConfigurations.cryodev-main.config.system.build.toplevel --dry-run
```

View file

@ -0,0 +1,183 @@
# Neuinstallation (Reinstall)
Diese Anleitung beschreibt die **Neuinstallation** eines bestehenden Hosts, z.B. nach Hardwarewechsel oder bei Problemen.
## Unterschied zur Erstinstallation
| Aspekt | Erstinstallation | Neuinstallation |
|--------|------------------|-----------------|
| SOPS-Secrets | Noch nicht vorhanden | Bereits konfiguriert |
| SSH-Host-Key | Neu generiert | **Muss wiederhergestellt werden!** |
| Disk-IDs | Neu ermitteln | Oft geändert (neue Hardware) |
| secrets.yaml | Wird erstellt | Bereits vorhanden |
## Wichtig: SSH-Host-Key Problem
Bei einer Neuinstallation wird ein **neuer SSH-Host-Key** generiert. Dieser stimmt nicht mehr mit dem Age-Key in `.sops.yaml` überein!
### Lösungsmöglichkeiten
**Option A: Alten Host-Key sichern und wiederherstellen** (empfohlen)
**Option B: Neuen Key generieren und SOPS aktualisieren**
## Voraussetzungen
- Backup des alten SSH-Host-Keys (falls Option A)
- Zugriff auf `.sops.yaml` und die Admin-Age-Keys
- Bootbares NixOS ISO
## Schritt 1: Vorbereitung (vor der Installation)
### 1.1 Alten SSH-Host-Key sichern (Option A)
Falls der alte Host noch läuft:
```bash
# Auf dem alten Host
sudo cat /etc/ssh/ssh_host_ed25519_key > ~/ssh_host_ed25519_key.backup
sudo cat /etc/ssh/ssh_host_ed25519_key.pub > ~/ssh_host_ed25519_key.pub.backup
```
Dateien sicher auf den Entwicklungsrechner kopieren.
### 1.2 Disk-IDs ermitteln
**Bei neuer Hardware** ändern sich die Disk-IDs!
```bash
# Im NixOS Live-System
lsblk -o NAME,SIZE,MODEL,SERIAL
ls -la /dev/disk/by-id/
```
Die neue Disk-ID in `hosts/<hostname>/disks.sh` oder `disks.nix` eintragen:
```bash
# Beispiel disks.sh
DISK="/dev/disk/by-id/nvme-Samsung_SSD_970_EVO_Plus_XXXXX"
```
## Schritt 2: Installation durchführen
### 2.1 NixOS ISO booten
Von USB/CD booten, Root-Passwort setzen, per SSH verbinden.
### 2.2 Repository klonen
```bash
sudo -i
nix-shell -p git
git clone <GIT_REPO_URL> /tmp/nixos
cd /tmp/nixos
```
### 2.3 Disk-Konfiguration prüfen
```bash
# Aktuelle Disk-IDs anzeigen
ls -la /dev/disk/by-id/
# Mit Konfiguration vergleichen
cat hosts/<hostname>/disks.sh | grep DISK
```
**Falls nötig:** Disk-ID in der Konfiguration anpassen.
### 2.4 Install-Script ausführen
```bash
bash scripts/install.sh -n <hostname>
```
### 2.5 SSH-Host-Key wiederherstellen (Option A)
**Vor dem Reboot!**
```bash
# Host-Key vom Backup wiederherstellen
cp /path/to/ssh_host_ed25519_key.backup /mnt/etc/ssh/ssh_host_ed25519_key
cp /path/to/ssh_host_ed25519_key.pub.backup /mnt/etc/ssh/ssh_host_ed25519_key.pub
chmod 600 /mnt/etc/ssh/ssh_host_ed25519_key
chmod 644 /mnt/etc/ssh/ssh_host_ed25519_key.pub
```
### 2.6 Reboot
```bash
umount -Rl /mnt
reboot
```
## Schritt 3: Nach dem Reboot
### Bei Option A (Key wiederhergestellt)
SOPS-Secrets sollten automatisch funktionieren. Testen:
```bash
sudo cat /run/secrets/tailscale/auth-key
```
### Bei Option B (Neuer Key)
Der Host kann die Secrets nicht entschlüsseln. Neuen Key konfigurieren:
```bash
# Neuen Age-Key ermitteln
nix-shell -p ssh-to-age --run 'cat /etc/ssh/ssh_host_ed25519_key.pub | ssh-to-age'
```
Auf dem Entwicklungsrechner:
```bash
# .sops.yaml aktualisieren mit neuem Key
vim .sops.yaml
# Secrets mit neuem Key neu verschlüsseln
sops updatekeys hosts/<hostname>/secrets.yaml
```
Dann Konfiguration neu deployen:
```bash
nixos-rebuild switch --flake .#<hostname> --target-host root@<IP>
```
## Häufige Probleme
### "No secret key available"
SOPS kann die Secrets nicht entschlüsseln. Ursache:
- SSH-Host-Key stimmt nicht mit Age-Key in `.sops.yaml` überein
Lösung: Option B durchführen (neuen Key konfigurieren).
### "Device not found" beim Partitionieren
Disk-ID in `disks.sh`/`disks.nix` ist falsch.
```bash
# Richtige ID finden
ls -la /dev/disk/by-id/
```
### Hardware-Config veraltet
Bei neuer Hardware muss `hardware.nix` neu generiert werden:
```bash
# Install-Script generiert automatisch neu, falls Datei fehlt
rm hosts/<hostname>/hardware.nix
bash scripts/install.sh -n <hostname>
```
## Checkliste
- [ ] Alten SSH-Host-Key gesichert (falls möglich)
- [ ] Disk-IDs in Konfiguration geprüft/aktualisiert
- [ ] Installation durchgeführt
- [ ] SSH-Host-Key wiederhergestellt ODER neuen Key in SOPS konfiguriert
- [ ] Secrets funktionieren (`sudo cat /run/secrets/...`)
- [ ] Tailscale verbunden (`tailscale status`)

View file

@ -0,0 +1,116 @@
# SD-Karten-Images für Raspberry Pi
Das Repository baut automatisch SD-Karten-Images für alle konfigurierten Raspberry Pi Hosts.
## Automatischer Build
Bei Änderungen an `main` werden automatisch Images für alle Pi-Hosts gebaut und als Release veröffentlicht.
**Download:** [Releases auf Forgejo](https://git.cryodev.xyz/steffen/cryodev-server/releases)
## Verfügbare Images
| Host | Image-Name |
|------|------------|
| `cryodev-pi` | `cryodev-pi-sd-image.img.zst` |
Neue Hosts werden automatisch gebaut, wenn sie zur Workflow-Matrix hinzugefügt werden.
## Image flashen
### 1. Herunterladen
```bash
wget https://git.cryodev.xyz/.../releases/latest/download/<hostname>-sd-image.img.zst
wget https://git.cryodev.xyz/.../releases/latest/download/<hostname>-sd-image.img.zst.sha256
# Checksum prüfen
sha256sum -c <hostname>-sd-image.img.zst.sha256
```
### 2. Dekomprimieren
```bash
zstd -d <hostname>-sd-image.img.zst -o <hostname>.img
```
### 3. Auf SD-Karte schreiben
```bash
# Richtiges Gerät finden
lsblk
# Schreiben (ACHTUNG: richtiges Gerät wählen!)
sudo dd if=<hostname>.img of=/dev/sdX bs=4M conv=fsync status=progress
```
Alternativ: `balenaEtcher` oder `Raspberry Pi Imager` verwenden.
## Was ist im Image?
- Vollständige NixOS-Installation für den spezifischen Host
- Alle konfigurierten Services (außer Secrets)
- SSH-Server aktiviert
- Automatische Root-Partition-Erweiterung beim ersten Boot
- Comin für automatische Updates
## Was fehlt?
**SOPS-Secrets** können nicht im Image enthalten sein (Henne-Ei-Problem mit SSH-Host-Key).
Nach dem ersten Boot:
1. Age-Key vom Pi holen
2. `.sops.yaml` aktualisieren
3. `secrets.yaml` erstellen
4. Konfiguration deployen
Siehe [Neuen Client hinzufügen](new-client.md) für die vollständige Anleitung.
## Neuen Host zur Pipeline hinzufügen
1. Host-Konfiguration in `hosts/<hostname>/` erstellen
2. In `.forgejo/workflows/build-pi-image.yml` zur Matrix hinzufügen:
```yaml
matrix:
host: [cryodev-pi, neuer-host] # <- hier hinzufügen
```
3. Push auf `main` → Image wird automatisch gebaut
## Manuell bauen
```bash
# Auf aarch64 (z.B. anderem Pi)
nix build .#nixosConfigurations.<hostname>.config.system.build.sdImage
# Auf x86_64 mit QEMU-Emulation (langsam)
nix build .#nixosConfigurations.<hostname>.config.system.build.sdImage \
--extra-platforms aarch64-linux
```
Voraussetzung auf x86_64:
```nix
{
boot.binfmt.emulatedSystems = [ "aarch64-linux" ];
}
```
## Troubleshooting
### Workflow schlägt fehl
- Prüfe ob `sd-image.nix` in der Host-Konfiguration importiert wird
- Prüfe ob binfmt auf cryodev-main aktiviert ist
### Image bootet nicht
- SD-Karte korrekt beschrieben?
- Andere SD-Karte versuchen
- Stromversorgung prüfen (min. 3A für Pi 4)
### Kein Netzwerk
- Ethernet-Kabel prüfen
- DHCP-Server im Netzwerk?