Files
homelab/doc/plan/homelab-manifest.md
T

233 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# homelab manifest
> Referenz für Aufbau und Betrieb meines Proxmox-Servers.
> Architekturarbeit + privat. Ein Mini-PC, 1× 1TB NVMe, 2× 4TB, 1× 2TB externe HDD.
> An dieses Dokument richte ich die Maschine aus — nicht umgekehrt.
---
## prinzipien
1. **Filesystem-first.** Das Dateisystem ist die Wahrheit. Web-UIs, SMB und Sync sind nur Clients darauf. Keine App "besitzt" die Daten allein.
2. **FOSS und self-hosted**, config-as-code. Jede Konfiguration (Caddyfile, compose, ZFS-Layout, Samba) liegt versioniert im Gitea.
3. **Öffentlich = Caddy, privat = WireGuard-only.** Nach aussen offen: nur der WireGuard-Port plus 80/443 für die öffentlichen Websites. Alles andere erreiche ich nur durch den Tunnel.
4. **RAID ist kein Backup.** 3-2-1: 3 Kopien, 2 Medien, 1 offsite.
5. **ZFS-Pool nie über ~85%.** Copy-on-Write braucht Luft. Auslastung wird überwacht, nicht geschätzt.
6. **Grosse Daten ≠ vzdump.** Bulk-Mounts laufen mit `backup=0`, separat gesichert per `zfs send`/Restic. vzdump nur für die schlanken rootfs.
7. **Bewusster Hybrid.** Single-purpose Infra → native LXC. Echte Multi-Container-App-Stacks → ein Docker-LXC pro Stack. Nie "ein Docker pro LXC für alles".
8. **Ein Werkzeug pro Aufgabe.** Lieber ein schlankes Tool das eine Sache gut macht als ein Monolith der alles halb kann.
9. **Reserve ist eingeplant**, nicht zufällig. Quotas sind Sicherheitsdeckel, kein starres Partitionieren.
---
## hardware & pools
| Pool | Medium | Topologie | nutzbar | Zweck |
|------|--------|-----------|---------|-------|
| `rpool` | 1× 1TB NVMe | Single-Disk ZFS | ~900 GiB | OS, alle rootfs, **Datenbanken**, oft gelesene Dienste |
| `tank` | 2× 4TB | **ZFS Mirror (RAID1)** | ~3.6 TiB | schwere Daten: Shares, Nextcloud, Immich, Paperless |
| — | 1× 2TB ext. HDD | — | ~1.8 TiB | lokales Backup-Ziel (`zfs recv` / Restic) |
ZFS-Settings beide Pools: `ashift=12`, `compression=lz4`, `atime=off`. Mirror überlebt einen Plattentod und heilt Bitrot beim Scrub (monatlich). NVMe ist Einzelplatte → keine Redundanz, aber nichts Unersetzliches liegt nur dort.
---
## dienste & container
Native LXC für Infra, ein Docker-LXC pro echtem App-Stack. CTID nach Rolle in Blöcken.
**[K]** = Kern (zuerst), **[+]** = Erweiterung (nach Bedarf).
| CTID | Dienst | Typ | rootfs | Daten | für | |
|------|--------|-----|--------|-------|-----|--|
| 100 | Caddy (Reverse Proxy) | native | 8G | — | beide | K |
| 101 | WireGuard (wg-easy) | docker | 4G | — | beide | K |
| 102 | Fileserver — Samba + Filebrowser + Syncthing | native | 8G | `tank/business`, `tank/private` | beide | K |
| 103 | AdGuard Home (DNS + Adblock) | native | 4G | — | beide | + |
| 110 | Nextcloud (app+db+redis) | docker | 40G | `tank/nextcloud` | privat | K |
| 111 | Immich (server+ML+db+redis) | docker | 60G | `tank/immich` | privat | K |
| 112 | Vaultwarden | native | 4G | — | beide | K |
| 113 | Paperless-ngx (DMS + OCR) | docker | 30G | `tank/paperless` | Arbeit | + |
| 114 | Stirling-PDF (PDF-Toolkit) | docker | 8G | — | Arbeit | + |
| 115 | Collabora Online (Office in NC) | docker | 16G | — | Arbeit | + |
| 116 | BookStack (Büro-Wiki / Detailbibliothek) | docker | 8G | — | Arbeit | + |
| 120 | Gitea | native | 8G | `tank/gitea` | Arbeit | K |
| 121 | CI-Runner (Forgejo/Woodpecker) | docker | 16G | — | Arbeit | + |
| 122 | Penpot (Open-Source Figma) | docker | 16G | — | Arbeit | + |
| 130+ | Websites (Hugo/static via Caddy) | native | 8G ea. | — | Arbeit | K |
| 140 | Uptime Kuma (Monitoring/Status) | docker | 8G | — | Betrieb | + |
| 141 | Beszel (System-/Pool-Metriken) | docker | 8G | — | Betrieb | + |
| 142 | Homepage (Dashboard / "Launcher") | docker | 4G | — | Betrieb | + |
| 160 | Jellyfin (Medien) | docker | 16G | `tank/media`* | privat | + |
| 161 | Navidrome (Musik) | native | 8G | `tank/media`* | privat | + |
| 162 | Linkwarden (Referenz-/Bookmark-Archiv) | docker | 16G | — | beide | + |
| 163 | Miniflux (RSS) | docker | 4G | — | privat | + |
Nummernschema: 100109 Infra/Netz · 110119 Cloud-Apps · 120129 Dev · 130139 Web · 140149 Betrieb · 160169 Medien/Privat. Lücken bleiben.
\* Medienbibliothek braucht eine bewusste Budget-Entscheidung — bei echter Film-Sammlung eher eine zusätzliche Platte einplanen statt den Tank zu sprengen.
---
## app-katalog: was sonst noch sinn macht
**Fürs Büro (stark empfohlen)**
- **Paperless-ngx** — Dokumentenarchiv mit OCR und Volltextsuche. Löst das Papierproblem: Verträge, Rechnungen, Baugesuche, Korrespondenz scannen → durchsuchbar. Watch-Ordner zieht Scans automatisch ein.
- **Stirling-PDF** — alles für PDFs: zusammenführen, teilen, OCR, komprimieren, signieren. Du lebst in Plan-PDFs und Eingaben.
- **Collabora Online** — Office-Dokumente direkt im Browser/in Nextcloud editieren. XLSX-kompatibel für Raumlisten.
- **BookStack** — Büro-Wiki: Detailbibliothek-Doku, Standards, Vorlagen, Projektwissen an einem Ort.
**Für den Betrieb des Homelabs**
- **Uptime Kuma** — weisst sofort wenn ein Dienst down ist (inkl. Push aufs Handy).
- **Beszel** (oder Netdata) — System- und Pool-Metriken → erfüllt die <85%-Alert-Regel.
- **Homepage** — eine Startseite die alle Dienste verlinkt, das DSM-Launcher-Gefühl.
**Privat**
- **AdGuard Home** — netzweiter Tracker-/Werbeblocker + interner DNS (löst gleich die internen Hostnamen).
- **Linkwarden** — visuelles Referenz-/Bookmark-Archiv. Beruflich top für Präzedenzfälle, Materialien, Detail-Ideen.
- **Jellyfin** — Filme/Serien, ergänzt Navidrome (Musik).
- **Miniflux** — minimalistischer RSS-Reader.
**Für deine Software (openbureau)**
- **CI-Runner** (Forgejo Actions / Woodpecker) — Tests + Auto-Deploy der Hugo-Site, Builds für Rapport/Dossier/Pendenz.
- **Penpot** — Open-Source Figma für UI/Mockups.
---
## der zugriff auf den share (die synology-erfahrung, nachgebaut)
Synologys Magie ist ein Bündel von Zugriffswegen auf *dieselben* Dateien. Filesystem-first nachgebaut, alles im Fileserver-LXC (102):
- **Samba** → klassisches Netzlaufwerk auf Mac/Linux/Windows. Voller nativer Speed für Rhino/CAD vom Desktop. Der Hauptzugang für die Arbeit.
- **Filebrowser** → Web-"File Station": browsen, hoch-/runterladen, **Share-Links** mit Passwort/Ablauf. Liest das FS live, kein DB-Desync. Auch im Handy-Browser brauchbar (PWA).
- **Syncthing** → das "Synology Drive": ausgewählte Ordner kontinuierlich auf Laptop syncen, offline arbeiten. Files bleiben *plain* auf der Platte → SMB funktioniert weiter parallel.
- **Homepage** → eine Kachel-Startseite über alles, der Launcher.
> Bewusst *nicht* Seafile: das wäre der bessere Sync-Client, speichert Dateien aber in eigenem Block-Format → dann ginge SMB auf denselben Daten nicht mehr. Verletzt filesystem-first.
---
## shares & datenstruktur
**Zwei getrennte Datasets** (= zwei Samba-Shares): saubere Trennung von Rechten, Snapshots und Backup-Priorität. Ein künftiger Mitarbeiter/Praktikant kriegt `business`, nie `private`.
### `tank/business` — Architekturbüro
Projektbezogen, Phasen nach SIA 102. Unterstriche sortieren Nicht-Projekt-Ordner nach oben.
```
business/
├── _vorlagen/ Planköpfe, Dokumentvorlagen, CAD-Templates
├── _bibliothek/
│ ├── details/ wiederverwendbare Konstruktionsdetails
│ ├── cad-blocks/
│ ├── materialien/
│ └── referenzen/ Präzedenzfälle, Vorbilder
├── _buro/ Administration, Buchhaltung, Marketing
└── projekte/
└── 2026-001_projektname/
├── 00_admin/ Verträge, Honorar, Protokolle, Korrespondenz
├── 01_grundlagen/ Bestand, Vermessung, Gutachten, Fotos
├── 02_vorstudien/ SIA 21 — Machbarkeit, Wettbewerb
├── 03_vorprojekt/ SIA 31
├── 04_bauprojekt/ SIA 32
├── 05_bewilligung/ SIA 33 — Baugesuch
├── 06_ausschreibung/ SIA 41
├── 07_ausfuhrung/ SIA 51/52/53 — Werkplanung, Baustelle
├── 08_abschluss/ Abnahme, Revision, Doku
├── cad/ Rhino .3dm (working)
├── plaene/ ausgegebene PDF-Pläne
├── visualisierung/ Renderings
└── fotos/ Baustellenfotos
```
Projektnummer `JJJJ-NNN_name` → sortierbar, gleiche Logik wie die CTIDs.
### `tank/private` — persönlich
```
private/
├── dokumente/ Verträge, Versicherung, Behörden
│ └── 2026/
├── finanzen/
├── studium/ HSLU Master — Module, Arbeiten, Thesis
├── projekte/ persönliche Projekte
├── scans/ Eingang für Paperless
└── archiv/
```
Nextcloud bleibt schlank für Kalender/Kontakte/Mobile und leichtes Teilen (eigenes `tank/nextcloud`). Optional kann es `tank/private` als External Storage einhängen, damit die App am Handy auch an die privaten Files kommt — mit dem bekannten Scan-Vorbehalt.
---
## speicher-aufteilung (thin + quota, mit reserve)
### tank — ~3.6 TiB nutzbar
| Dataset | Quota | Zweck |
|---------|-------|-------|
| `tank/business` | **1.3 TiB** | Architekturarbeit (SMB + Filebrowser + Syncthing) |
| `tank/immich` | **600 GiB** | Foto-/Videobibliothek |
| `tank/private` | **300 GiB** | persönliche Files (SMB + Filebrowser + Syncthing) |
| `tank/paperless` | **150 GiB** | Dokumentenarchiv |
| `tank/nextcloud` | **150 GiB** | Sync/Mobile/Teilen |
| `tank/dump` | **150 GiB** | vzdump der rootfs |
| `tank/gitea` | **50 GiB** | Repos |
| **Summe Quotas** | **~2.7 TiB** | = ~72% bei voll ausgereizten Quotas |
| **freie Reserve** | **~0.9 TiB** | bewusst unallokiert → Pool bleibt unter 85% |
> Quotas sind Deckel, nicht Reservierungen. Sie dürfen den Pool in Summe überschreiten — hier tun sie's bewusst *nicht*, damit selbst bei vollen Quotas Luft bleibt. Medien (Jellyfin) würden diese Reserve fressen → eigene Platte einplanen.
### rpool — ~900 GiB nutzbar
OS + ARC + alle rootfs (Kern + Erweiterungen): grob **~350 GiB**. Datenbanken liegen in den rootfs auf der NVMe (schnelle Random-IO). **Reserve ~550 GiB** — bewusst grosszügig: Snapshots, künftige Dienste, Option ein heisses Dataset (z.B. Immich-Thumbnails) auf die NVMe zu pinnen.
---
## mount-konventionen
Zwei Fälle, bewusst unterschiedlich:
- **Exklusive Service-Daten** (Nextcloud, Immich, Paperless, Gitea) → Proxmox-verwalteter Mountpoint, eigenes subvol:
```
mp0: tank/nextcloud,mp=/data,backup=0,size=150G
```
- **Geteilte Datasets** (`business`, `private`, von Samba+Filebrowser+Syncthing im selben LXC genutzt) → **Bind-Mount** des Host-Pfads:
```
mp0: /tank/business,mp=/srv/business
mp1: /tank/private,mp=/srv/private
```
`backup=0` auf allen grossen Mounts. Dataset-Settings nach Inhalt: `recordsize=1M` für Immich/Renderings, Default 128K sonst.
---
## netz & zugriff
- **Öffentlich:** Router → nur 80/443 → Caddy (100), macht TLS und routet zu den öffentlichen Websites. Sonst nichts nach aussen.
- **Privat:** Router → nur WireGuard-UDP → wg-easy (101). Proxmox-UI, Nextcloud, Immich, Vaultwarden, Filebrowser, Paperless: **nur** durch den Tunnel über interne Hostnamen.
- **Interne Namen** über AdGuard (103) als DNS + Caddy als internen Proxy → keine IPs merken.
---
## backup-strategie (3-2-1)
1. **Snapshots** (sanoid) auf allen `tank`-Datendatasets — Schutz gegen "ups, gelöscht".
2. **Lokal:** `zfs send`/Restic der wichtigen Datasets + `tank/dump` → 2TB externe HDD.
3. **Offsite:** Restic der Unersetzlichen (`business`, `private`, `immich`, `nextcloud`, `paperless`, `gitea`, `vaultwarden`) → Hetzner Storage Box, verschlüsselt + versioniert.
> RAID gegen Plattentod. Snapshots gegen Fehler. Offsite gegen Brand und Ransomware. Alle drei. **Restore mindestens einmal testen** — ein ungetestetes Backup ist kein Backup.
---
## checkliste
- [ ] Proxmox auf NVMe, `rpool` als Single-Disk ZFS
- [ ] `tank` als Mirror, Settings setzen, Scrub-Cron
- [ ] Datasets + Quotas anlegen
- [ ] Fileserver-LXC (102): Samba (2 Shares) + Filebrowser + Syncthing
- [ ] Ordnerstruktur business/private anlegen
- [ ] Caddy + WireGuard + AdGuard (Netzgerüst)
- [ ] Kern-Apps (NC, Immich, Vaultwarden, Gitea), dann Erweiterungen nach Bedarf
- [ ] Monitoring (Uptime Kuma, Beszel) + Pool-Alert <85%
- [ ] sanoid + Restic offsite, **Restore testen**