DoItYourself
Beschreibung des Versuchs, statt eine NAS Distribution oder einen Hypervisor zu verwenden, einen eigenen Server zusammenzustellen.
Die Hintergründe
TrueNAS und auch Proxmox bieten soviel mehr als ich brauche und haben ihre eigene Komplexität. Wenn ich darüber nachdenke, was ich für die nähere Zukunft benötige, dann ist das eigentlich nicht viel.
- Ein gutes Filesystem für die Daten: ZFS.
- Homelab Standard zum hosten von Services mit möglichst guten Informationen online: docker compose
- Gängige Pakete direkt am Host installierbar haben: apt Paketmanager bei Debian basierten Distributionen.
- Open Source wenn sinnvoll einsetzbar
- Wireguard Netzwerk um keine Ports zuhause öffnen zu müssen: tailscale oder netbird
Das kann ich mit einer Server Distribution wie Debian Server oder Ubuntu Server
erreichen. Ubuntu ist in der Serverwelt ein bekannter Name und ich kann mir
vorstellen, dass das Ein oder Andere mit Ubuntu einfacher zu erreichen ist als
mit Debian. Sollte Cannonical (Firma hinter Ubuntu) mal verrückt spielen, ist
der Umstieg zu Debian sicherlich gut machbar. Also probiere ich es mit
Trommelwirbel:
Ubuntu Server.
Die Installation
Ist einfach. Ich habe mich durch den Installer durchgearbeitet und sinnvolle Defaults genommen. Die einzige Besonderheit ist, dass ich den SSH Server mit aktiviert habe. So kann ich per SSH den Server konfigurieren.
micronas ade, hallo hpmicro
Das ist der neue Hostname. Nach dem Neustart verbinde ich mich per SSH auf den Server. Danach erledige ich die Basics. Updaten:
&&
Das Basissetup
Jetzt dokumentiere ich Schritt für Schritt, was ich manuell durchführe. In Zukunft werde ich wohl ein Skript dafür bauen.
ZFS installieren und ersten Pool erstellen
ZFS installieren scheint recht leicht zu sein:
Dann erstelle ich einen Pool. Ich habe 4 4TB HDDs, 2 kleine SSDs für den Pool zur Verfügung. Aktuell brauche ich noch nicht soviel Platz. Also erstelle ich folgendes Layout:
- 3 HDDs Raid Z1: Damit kann mir eine HDD ausfallen und ich habe 8 TB Speicherplatz.

- 1 HDD als Hot Spare. Die sollte automatisch einspringen, sollte eine der 3
HDDs aus dem Pool ausfallen. Dabei muss ich die Eigenschaft autoreplace
aktivieren

- 2 SSDs nutze ich zum Beschleunigen des Pools: Hier probiere ich einen Mirror
als "ZFS Special Device" aus. Diese können laut einer Beschreibung in
der Proxmox Dokumentation sowohl
Metadaten, Deduplication Tables und kleine Dateien speichern. Das ist für mich
interessant, weil so die großen Dateien auf den HDDs gespeichert sind und die
kleinen Dateien auf den schnellen SSDs.
Damit die kleinen Dateien wirklich auf die SSDs geschrieben werden, muss ich
das für den Pool generieren. Achtung:
special_small_blocks muss kleiner sein als die recordsize!
Damit ist der Pool denke ich fürs Erste vorbereitet für die Nutzung.
Erste ZFS Datasets erstellen
Ich starte mit einer sehr einfachen Basisstruktur:
- app: Peristent Volumes für Docker Services und vergleichbares.
- backup: Backups, insbesondere von anderen Hosts. Ich werde langfristig
mehrere Hosts haben und die können gegenseitig ein Backup Ziel sein. Durch das
Backup Dataset erkenne ich schnell und einfach, wo die Backups sind oder
gespeichert werden sollen. Hier konfiguriere ich auch eine Kompression um
Speicherplatz zu sparen.

Snapshots einrichten
Hierfür will ich sanoid und syncoid verwenden. Das ist im Ubuntu Repository, also ist die Installation schnell erledigt:
Die Datei sanoid.conf passe ich nur leicht an. Ich ergänze die beiden Datasets.
[tank/app]
production
zfs
[tank/backup]
backup
zfs
Bis ich rausgefunden habe, ob der Timer für das automatische Erstellen von Snapshots automatisch aktiviert wird (ja wird er!), wurde schon der erste Snapshot erstellt:
Für mich zur Dokumentation, ein Rollback läuft mit:
Es gibt auch einen einfachen Monitor Befehl:
Der zeigt gerade kritische Fehler an, weil ich noch keine Daily Snapshopts habe. Ist logisch, habe sanoid erst jetzt aktiviert. Das werde ich die Tage nochmal prüfen.
Backups einrichten
Ich möchte von Anfang an die Backups nach Best Practices einrichten. Dazu gehört für mich, das nicht mit dem root User zu machen, sondern mit dezidierten Usern, die keine root Rechte besitzen. Dafür gibt es einen guten Blog Post bei klarasystems: Improving Replication Security With OpenZFS Delegation Systemuser anlegen:
Für den Datenaustausch braucht es ssh keys. Diese generiere ich ohne Passwort.
Das Private key File (ohne .pub) kopiere ich zu /home/recvuser/.ssh/syncoid. Den Inhalt des syncoid.pub Files kopiere ich ergänze ich im File /home/senduser/.ssh/authorized_keys senduser die notwendigen Rechte für tank/app geben:
recvuser die notwendigen Rechte für tank/backup erlauben:
Jetzt kommt syncoid ins Spiel. Hier ist es noch alles am gleichen host und daher recht sinnlos. Aber zum Testen passt das schon einmal und sobald ich einen weiteren Host ergänze, werde ich das um die Ziellösung erweitern.
Ich aktiviere wieder den Mountpoint, damit ich die Daten des Backups leicht prüfen kann. Den Mountpoint hatte ich zuvor wegen Fehlermeldungen deaktiviert:
Damit syncoid automatisch läuft, erstelle ich einen Systemd Service mit Timer und speichere sie in /etc/systemd/system/
syncoid.service:
[Unit]
Description=Backup ZFS filesystems
Documentation=man:syncoid(8)
Requires=local-fs.target
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
Environment=TZ=UTC
User=recvuser
ExecStart=/usr/sbin/syncoid --recursive --no-privilege-elevation --no-sync-snap --sshkey /home/recvuser/.ssh/syncoid senduser@localhost:tank/app tank/backup/hpmicro/app
syncoid.timer:
[Unit]
Description=Run Syncoid hourly
[Timer]
OnCalendar=hourly
Persistent=true
[Install]
WantedBy=timers.target
Wichtig nach dem Erstellen der Systemd - Dateien sind folgende Befehle für die Aktivierung der Services:
Snapshots und Backups prüfen
Das Mounten eines Snapshots ist leicht möglich und funktioniert recht intuitiv.
Damit ließen sich auch einzelne Files oder Directories von einem Snapshot oder Backup wiederherstellen. Natürlich nur, wenns nötig ist.
Docker einrichten
Für die Installation nutze ich das
Convenience Script:

Monitoring einrichten
Hierfür verwende ich zum Start einen ganz neuen Docker Service
CoreControl.

Das compose.yml sieht wie folgt aus:
services:
web:
image: haedlessdev/corecontrol:latest
restart: unless-stopped
ports:
- "3000:3000"
environment:
JWT_SECRET: ${JWT_SECRET}
DATABASE_URL: "postgresql://postgres:postgres@db:5432/postgres"
agent:
image: haedlessdev/corecontrol-agent:latest
restart: unless-stopped
environment:
DATABASE_URL: "postgresql://postgres:postgres@db:5432/postgres"
depends_on:
db:
condition: service_healthy
db:
image: postgres:17
restart: unless-stopped
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: postgres
volumes:
- ./postgres_data:/var/lib/postgresql/data
healthcheck:
test:
interval: 2s
timeout: 2s
retries: 10
Die .env Datei hat nur eine Zeile Inhalt:
JWT_SECRET="<random string"
Und es braucht fürs Monitoring einen glances Container. Hierfür mache ich einen eigenen Ordner tank/app/glances und kopiere folgendes compose.yml hinein:
services:
glances:
image: nicolargo/glances:latest
container_name: glances
restart: unless-stopped
ports:
- "61208:61208"
pid: "host"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- GLANCES_OPT=-w --disable-webui
Mit docker compose up -d sind die Services gestartet und schon kann ich
im Web-UI von CoreControl den ersten Server konfigurieren und die Monitoring
Daten übersichtlich dargestellt betrachten.
Ob ich bei CoreControl bleibe, das ist noch nicht so sicher. Aber jetzt habe
ich einen ersten Ubuntu Server mit ZFS, Snapshopts und Backups und laufenden
Docker Services. Das ist eine gute Basis.
Der nächste Schritt ist voraussichtlich, die Daten meines aktuellen Proxmox
Hosts hierher zu sichern und den Host als Ubuntu Server neu zu installieren.
Aber das ist einer der nächsten Posts.
Matthias