8.0 KiB
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.
zpool status # rpool sollte ONLINE sein
zfs set atime=off rpool
2 — tank (mirror) anlegen
Disk-IDs holen (nie /dev/sdX verwenden — die wandern):
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:
echo '0 3 1 * * root /sbin/zpool scrub tank' > /etc/cron.d/zfs-scrub
3 — datasets & quotas
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:
pct set 110 -mp0 tank/nextcloud,mp=/data,backup=0
Fileserver (102) braucht die geteilten Datasets als Bind-Mount (mehrere Dienste im selben LXC):
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:
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):
apt install -y samba
groupadd buro; useradd -M -G buro karim; smbpasswd -a karim
/etc/samba/smb.conf (Auszug):
[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
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:
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
# 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 }
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:
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:
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:
[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):
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
- 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.