Runbook: Reboot von NUC und Hetzner¶
Geplanter Neustart beider Server mit Prüfliste davor und danach. Erstellt für homeserver#196.
Die Liste prüft Wirkung, nicht Zustand: dass ein Container läuft, heißt nicht, dass er seine Daten sieht. Genau dafür sind die Kommandos unten da.
Vorbedingung: die Startreihenfolge auf dem NUC¶
docker.service hat keine Abhängigkeit zu den Mount-Units — es ist nur nach
network-online.target geordnet. Die fünf Netzwerk-Mounts sind zwar Before=multi-user.target,
Docker aber auch; zueinander sind sie damit nicht geordnet.
Folge: Docker kann Container starten, bevor NFS und die Storage Box bereit sind. Ein
Bind-Mount wird beim Containerstart aufgelöst — zeigt /mnt/unas in dem Moment noch auf das
leere lokale Verzeichnis, arbeitet der Container dauerhaft darauf weiter, auch wenn das NFS
Sekunden später einhängt. Betroffen wären Immich, Paperless, der Media-Stack und die
5-Jahres-Daten von VictoriaMetrics und VictoriaLogs.
Vor dem ersten Reboot nach dieser Liste einmalig setzen:
sudo mkdir -p /etc/systemd/system/docker.service.d
sudo tee /etc/systemd/system/docker.service.d/10-wait-for-mounts.conf >/dev/null <<'EOF'
[Unit]
RequiresMountsFor=/mnt/ssd /mnt/unas /mnt/pictures /mnt/monitoring /mnt/paperless /mnt/storagebox
EOF
sudo systemctl daemon-reload
Danach die Wirkung prüfen, nicht den Dateiinhalt — ein Drop-in ohne Sektionskopf wird zeilenweise still verworfen:
systemctl show docker.service -p RequiresMountsFor
# erwartet: RequiresMountsFor=/mnt/ssd /mnt/unas ... (nicht leer)
Während des NUC-Reboots ist das Haus ohne DNS
Pi-hole auf dem NUC ist der DNS-Server für 10.10.10.0/24. Solange der NUC neu startet,
löst im LAN nichts auf — kein Streaming, kein Smart Home, nichts. Vorher prüfen, ob auf
der UDM ein zweiter DNS-Server hinterlegt ist, und Lars vorher Bescheid geben.
Reihenfolge¶
Erst Hetzner, dann NUC. Auf dem Hetzner laufen Uptime Kuma und ntfy, also der Weg, auf dem eine Störung gemeldet wird. Den will man beim riskanteren der beiden Neustarts oben haben. Umgekehrt merkt man einen misslungenen NUC-Reboot erst, wenn man selbst nachsieht.
Teil 1 — Hetzner vServer¶
Vorher¶
ssh <hetzner>
uptime && uname -r
cat /var/run/reboot-required 2>/dev/null || echo "(kein Flag)"
docker ps --format '{{.Names}}\t{{.Status}}' | tee /tmp/vorher-container.txt
docker ps -q | wc -l # Anzahl merken
Reboot¶
Nachher¶
uname -r # neuer Kernel aktiv?
docker ps -q | wc -l # gleiche Anzahl wie vorher?
docker ps -a --filter status=exited --filter status=restarting --format '{{.Names}}'
# leer erwartet
Von außen gegenprüfen — diese vier decken Authelia, lldap, Headscale und die Alarmkette ab:
for u in https://ntfy.homelab-external.robinwerner.net \
https://headscale.homelab-external.robinwerner.net \
https://uptime.homelab-external.robinwerner.net \
https://auth.homelab-external.robinwerner.net; do
printf '%-60s ' "$u"; curl -s -o /dev/null -w '%{http_code}\n' --max-time 8 "$u"
done
Tailnet prüfen (vom NUC aus): docker exec tailscale tailscale status — hetzner-server
muss wieder active sein und idealerweise direct, nicht über DERP.
Teil 2 — Intel NUC¶
Vorher¶
uptime && uname -r
cat /var/run/reboot-required.pkgs 2>/dev/null # welches Paket verlangt den Reboot
free -h # Swap-Stand notieren
docker ps -q | wc -l # Container-Anzahl merken
docker ps --format '{{.Names}}\t{{.Status}}' > /tmp/vorher-container.txt
Kein Backup darf laufen — borgmatic mitten im Lauf abzuschneiden hinterlässt ein Lock im Repo:
systemctl is-active borgmatic.service # "inactive" erwartet
systemctl list-timers borgmatic.timer --no-pager
Läuft gerade eines, entweder abwarten oder den Timer für die Dauer stoppen.
Reboot¶
Nachher — in dieser Reihenfolge¶
1. Mounts zuerst. Vor allem anderen, weil daran alles Weitere hängt:
for m in /mnt/ssd /mnt/unas /mnt/pictures /mnt/monitoring /mnt/paperless \
/mnt/storagebox /mnt/borg-repo /mnt/borg-repo-aiserver; do
printf ' %-26s ' "$m"; mountpoint -q "$m" && echo ok || echo FEHLT
done
Fehlt einer, nicht weitermachen: erst den Mount reparieren, dann die betroffenen Stacks
mit docker compose up -d --force-recreate neu erstellen, damit sie den Mount auch sehen.
2. Host-Dienste:
3. Container:
docker ps -q | wc -l # gleiche Anzahl wie vorher
docker ps -a --filter status=exited --filter status=restarting --format '{{.Names}}'
docker ps --filter health=unhealthy --format '{{.Names}}'
4. Sehen die Container ihre Daten? Der eigentliche Test — ein leerer Bind-Mount fällt sonst tagelang nicht auf:
docker exec immich_server ls /usr/src/app/upload >/dev/null && echo "immich ok"
docker exec victorialogs ls /vlogs >/dev/null && echo "vlogs ok"
docker exec victoriametrics ls /storage >/dev/null && echo "vmetrics ok"
5. DNS und Netz:
6. Traefik und Anwendungen:
curl -s http://127.0.0.1:8082/metrics | grep -c '^traefik_' # > 0
curl -s -o /dev/null -w 'HA %{http_code}\n' --max-time 5 http://10.10.10.3:8123/
Dazu einmal im Browser: grafana.home.robinwerner.net, fotos.home.robinwerner.net,
paperless.home.robinwerner.net. Die decken Traefik-Routing, Zertifikate und die drei
Stacks mit den größten Datenmengen ab.
7. Swap: free -h — nach dem Neustart nahe null. War er vorher voll, ist das der
Normalzustand und kein Grund zur Sorge; bleibt er binnen Tagen wieder bei 100 %, gehört das
untersucht.
Wenn etwas fehlt¶
| Symptom | Erster Griff |
|---|---|
| Ein Mount fehlt | systemctl status mnt-<name>.mount, dann systemctl start — bei NFS zuerst prüfen, ob die UNAS Pro erreichbar ist |
| Container läuft, Daten fehlen | Mount war beim Start noch nicht da → Mount richten, dann docker compose up -d --force-recreate <stack> |
| Kein DNS im LAN | docker ps --filter name=pihole; notfalls an der UDM übergangsweise einen öffentlichen Resolver setzen |
| Traefik liefert kein Zertifikat | docker logs traefik \| grep -i acme; /mnt/ssd/container-data/traefik/letsencrypt muss gemountet sein |
| Tailnet bleibt offline | docker logs tailscale; Headscale auf dem Hetzner erreichbar? |
Stand bei Erstellung (06.09.2026)¶
| NUC | Hetzner | |
|---|---|---|
| Uptime | 100 Tage | — |
| Kernel | 5.15.0-179-generic |
— |
| Reboot verlangt von | libc6 |
Kernel-Update seit 29.07. |
| Swap | 4,0 GiB von 4,0 GiB belegt | — |
| Container | 65, alle mit Restart-Policy | — |
Alle Mount-Units auf dem NUC (mnt-unas, mnt-pictures, mnt-monitoring, mnt-paperless,
mnt-storagebox) sind enabled und kommen nach dem Neustart von selbst zurück — die
Reihenfolge gegenüber Docker ist der offene Punkt, siehe Vorbedingung oben.