# homelab — aufbau-anleitung Schritt-für-Schritt nach dem Manifest. Reihenfolge ist bewusst: erst Fundament (Pools, Datasets), dann Netzgerüst (Caddy/WireGuard/DNS), dann Apps. Domains und IPs hier als Platzhalter (`deinedomain.ch`, `10.0.0.x`) — anpassen. --- ## 1 — proxmox & rpool Proxmox-Installer von USB. Bei der Disk-Auswahl die NVMe nehmen, Filesystem **zfs (RAID0)** (= Single-Disk ZFS), `ashift=12`, compression `lz4`. Das wird dein `rpool`. Nach dem ersten Boot: Enterprise-Repo raus, No-Subscription-Repo rein, updaten. ```bash zpool status # rpool sollte ONLINE sein zfs set atime=off rpool ``` --- ## 2 — tank (mirror) anlegen Disk-IDs holen (nie /dev/sdX verwenden — die wandern): ```bash ls -l /dev/disk/by-id/ | grep -i ata # die zwei 4TB-Platten identifizieren zpool create -o ashift=12 \ -O compression=lz4 -O atime=off -O xattr=sa \ tank mirror /dev/disk/by-id/PLATTE1 /dev/disk/by-id/PLATTE2 zpool status tank # mirror, beide ONLINE ``` Monatlichen Scrub einrichten: ```bash echo '0 3 1 * * root /sbin/zpool scrub tank' > /etc/cron.d/zfs-scrub ``` --- ## 3 — datasets & quotas ```bash zfs create -o quota=1300G tank/business zfs create -o quota=300G tank/private zfs create -o quota=600G -o recordsize=1M tank/immich zfs create -o quota=150G tank/paperless zfs create -o quota=150G tank/nextcloud zfs create -o quota=150G tank/dump zfs create -o quota=50G tank/gitea zfs list -o name,quota,used tank # kontrollieren ``` `tank/dump` als Proxmox-Backup-Storage eintragen: Datacenter → Storage → Add → Directory, Pfad `/tank/dump`, Inhalt "VZDump backup file". --- ## 4 — LXC-muster & mountpoints Pro Container: rootfs auf `rpool`, Bulk-Daten auf `tank`. Beispiel Nextcloud (CTID 110), exklusives Dataset → verwalteter Mountpoint: ```bash pct set 110 -mp0 tank/nextcloud,mp=/data,backup=0 ``` Fileserver (102) braucht die **geteilten** Datasets als Bind-Mount (mehrere Dienste im selben LXC): ```bash pct set 102 -mp0 /tank/business,mp=/srv/business pct set 102 -mp1 /tank/private,mp=/srv/private ``` **Hinweis unprivilegierte LXC:** in-container UID wird um 100000 verschoben. Damit Schreiben klappt, dem Dataset die verschobene UID/GID geben, z.B. für in-container `1000`: ```bash chown -R 101000:101000 /tank/business /tank/private ``` Tipp: alle drei Zugriffsdienste (Samba/Filebrowser/Syncthing) **im selben LXC 102** halten — dann gibt es keine container-übergreifenden UID-Probleme. --- ## 5 — fileserver: samba + filebrowser + syncthing (LXC 102) Debian-LXC, dann: **Samba** (zwei Shares): ```bash apt install -y samba groupadd buro; useradd -M -G buro karim; smbpasswd -a karim ``` `/etc/samba/smb.conf` (Auszug): ```ini [business] path = /srv/business valid users = @buro read only = no force group = buro create mask = 0660 directory mask = 0770 [private] path = /srv/private valid users = karim read only = no create mask = 0600 directory mask = 0700 ``` ```bash systemctl restart smbd ``` Mounten am Mac: Finder → ⌘K → `smb://10.0.0.102/business`. Linux: `mount -t cifs //10.0.0.102/business /mnt/business -o user=karim`. **Filebrowser** (Web + Share-Links), rooted über beide Shares: ```bash curl -fsSL https://raw.githubusercontent.com/filebrowser/get/master/get.sh | bash filebrowser config init filebrowser config set --root /srv --address 0.0.0.0 --port 8080 filebrowser users add karim DEINPASSWORT --perm.admin ``` Als systemd-Service einrichten (Unit anlegen, enable). Caddy proxyt später `files.deinedomain.ch` → `10.0.0.102:8080`. **Syncthing** (das "Drive"): `apt install syncthing`, als User-Service starten, Web-UI auf `:8384`, Ordner `/srv/business` (oder gezielte Unterordner) freigeben und auf dem Laptop verbinden. Da Syncthing plain files schreibt, bleibt SMB parallel nutzbar. --- ## 6 — ordnerstruktur anlegen ```bash # business mkdir -p /srv/business/{_vorlagen,_buro,_bibliothek/{details,cad-blocks,materialien,referenzen},projekte} mkdir -p /srv/business/projekte/2026-001_beispiel/{00_admin,01_grundlagen,02_vorstudien,03_vorprojekt,04_bauprojekt,05_bewilligung,06_ausschreibung,07_ausfuhrung,08_abschluss,cad,plaene,visualisierung,fotos} # private mkdir -p /srv/private/{dokumente/2026,finanzen,studium,projekte,scans,archiv} chown -R 101000:101000 /srv/business /srv/private ``` Für neue Projekte das `2026-001_beispiel`-Gerüst als Vorlage kopieren (oder ein kleines Skript in `_vorlagen/` ablegen). --- ## 7 — caddy (LXC 100) `apt install caddy`, dann `/etc/caddy/Caddyfile`: ``` files.deinedomain.ch { reverse_proxy 10.0.0.102:8080 } cloud.deinedomain.ch { reverse_proxy 10.0.0.110:80 } fotos.deinedomain.ch { reverse_proxy 10.0.0.111:2283 } www.deinedomain.ch { root * /srv/www; file_server } ``` ```bash systemctl reload caddy ``` Caddy holt TLS automatisch. Am Router nur 80/443 auf Caddy forwarden. --- ## 8 — wireguard (LXC 101, wg-easy) Docker im LXC, wg-easy gibt dir eine GUI für Peers: ```bash docker run -d --name wg-easy --cap-add NET_ADMIN --cap-add SYS_MODULE \ -e WG_HOST=vpn.deinedomain.ch -e PASSWORD_HASH='...' \ -p 51820:51820/udp -p 51821:51821/tcp \ -v ~/.wg-easy:/etc/wireguard --restart unless-stopped \ ghcr.io/wg-easy/wg-easy ``` Am Router **nur** UDP 51820 forwarden. Peers in der UI anlegen, QR scannen. Im Tunnel erreichst du das interne Subnetz → alle privaten Dienste, ohne sie je öffentlich zu machen. --- ## 9 — adguard home (LXC 103) Installieren, als DNS im Router (oder im WireGuard-Profil) setzen. Interne A-Records anlegen, damit `cloud.deinedomain.ch` etc. intern auf die LXC-IPs zeigen → gleiche Hostnamen drinnen wie draussen. --- ## 10 — app-stacks (NC, immich, paperless) Pro Stack ein Docker-LXC, compose-File ins Gitea. Muster für **Nextcloud** (110): - compose mit `app`, `db` (Postgres), `redis`. Volumes für App/DB auf rootfs (NVMe). - Daten-Volume auf das gemountete `/data` (= `tank/nextcloud`). - Caddy proxyt `cloud.deinedomain.ch`. **Immich** (111) und **Paperless-ngx** (113) analog — offizielle compose-Files nehmen (ändern sich regelmässig, drum upstream statt hier einfrieren) und nur den Daten-Pfad auf das jeweilige `tank/...`-Mount zeigen. Paperless' Consume-Ordner auf `/srv/private/scans` zeigen lassen → Scans landen automatisch im Archiv. --- ## 11 — monitoring - **Uptime Kuma** (140): jeden Dienst als HTTP-Check anlegen, Push aufs Handy (ntfy/Telegram). - **Beszel** (141): Agent auf dem Proxmox-Host, Pool-Auslastung im Blick. - **Pool-Alert <85%** als simpler Cron: ```bash cat > /etc/cron.hourly/zfs-capacity << 'EOF' #!/bin/bash cap=$(zpool list -H -o capacity tank | tr -d '%') [ "$cap" -ge 85 ] && echo "tank $cap%" | ntfy publish homelab EOF chmod +x /etc/cron.hourly/zfs-capacity ``` --- ## 12 — backup (sanoid + restic) **Snapshots** (sanoid) — `/etc/sanoid/sanoid.conf`: ```ini [tank/business] use_template = prod [tank/private] use_template = prod [tank/immich] use_template = prod [template_prod] hourly = 24 daily = 30 monthly = 6 autosnap = yes autoprune = yes ``` **Offsite** zur Hetzner Storage Box (Restic über SFTP): ```bash export RESTIC_REPOSITORY="sftp:uXXXXX@uXXXXX.your-storagebox.de:/backup" export RESTIC_PASSWORD_FILE=/root/.restic-pw restic init restic backup /tank/business /tank/private /tank/nextcloud /tank/immich /tank/paperless /tank/gitea restic forget --keep-daily 14 --keep-weekly 8 --keep-monthly 12 --prune ``` In einen täglichen Cron packen. **Restore-Test (Pflicht):** einmal `restic restore latest --target /tmp/restoretest --include /tank/private/dokumente` und prüfen ob die Files stimmen. Ein ungetestetes Backup ist kein Backup. --- ## reihenfolge auf einen blick 1. Proxmox + rpool → 2. tank Mirror + Scrub → 3. Datasets + Quotas → 4. Fileserver (Samba/Filebrowser/Syncthing) + Ordner → 5. Caddy + WireGuard + AdGuard → 6. Kern-Apps → 7. Monitoring → 8. Backup + Restore-Test → 9. Erweiterungen nach Lust.