Bisher war die H:-Nearline-Kopie nur als Backup-Ziel beschrieben (CAPACITY_AND_LIFECYCLE), nicht als Restore-Quelle. Im Ernstfall fehlte der Hinweis, dass auf baerchen eine frische lokale Kopie aller Dumps + Bundles liegt. - ops/h-drive-nearline/README.md: neuer Abschnitt "Restore aus H:/ (DR-Fall)" mit Inhalt, Rueckspiel-Weg (-> RESTORE_MATRIX / SERVICES_RECOVERY) und Pflicht-Frische-Pruefung (deckt den S4U-Stale-Fall ab). - docs/DISASTER_RECOVERY.md: baerchen-Abschnitt verweist jetzt auf die H:-Fallback-Restore-Quelle und das Runbook. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
H:/ Nearline-Backup — Struktur und Betrieb
Stand: 2026-06-21
Rolle der H:/
Die externe HDD (asmedia ASM235, 7.4 TB, Laufwerk H:) dient ausschließlich als
Nearline-Backup-Spiegel für kritische Dumps und Git-Bundles.
Sie ist kein Primär-Backup (das ist Hetzner/Borg) und kein dauerhaftes Archiv.
Sollzustand
H:\
└── kallilab-nearline-backups\
├── borg-dumps\latest\ ← aktuelle DB-Dumps (per Script)
├── git-bundles\gitea\ ← Gitea-Repo-Bundles (per Script)
├── _dr-kit\ ← SSH-Keys, Offline-Secrets (manuell)
├── _logs\ ← Robocopy-Logs je Lauf
└── _reports\ ← Markdown-Reports je Lauf
Nichts weiteres gehört dauerhaft auf die H:/. Temporäre Recovery- oder Backup-Ordner aus Notfallsituationen sind nach Abschluss zu löschen.
Restore aus H:/ (DR-Fall)
Wenn Unraid/Hetzner nicht erreichbar sind, ist die H:/ die schnellste lokale
Quelle für die aktuellsten DB-Dumps und Gitea-Bundles. Sie ersetzt nicht die
Hetzner-Borg-Kette (Einordnung: docs/CAPACITY_AND_LIFECYCLE.md), verkürzt aber
den Wiederanlauf, solange die Artefakte frisch sind.
Inhalt und Restore-Weg:
- DB-Dumps:
H:\kallilab-nearline-backups\borg-dumps\latest\*— dieselben Dateien wie/mnt/user/backups/borg/dumps/latest. Im DR-Fall auf den neu aufgesetzten Host nach/mnt/user/backups/borg/dumps/latestzurückspielen (SMB/Robocopy), dann pro Dienst nachdocs/RESTORE_MATRIX.mdeinspielen. - Gitea-Bundles:
H:\kallilab-nearline-backups\git-bundles\gitea\— bare Repo-Bundles für den Gitea-Bootstrap (Reihenfolge:docs/SERVICES_RECOVERY.md). - DR-Kit (Keys/Secrets):
H:\kallilab-nearline-backups\_dr-kit\— SSH-Keys und Offline-Secrets, siehe Abschnitt_dr-kitunten.
Vor dem Verlassen auf H:/ immer die Frische prüfen: Die LastWriteTime der Dumps muss vom selben Tag sein (
Get-ChildItem H:\kallilab-nearline-backups\borg-dumps\latest). Ein still veralteter Spiegel (siehe S4U-Vorfall unten) ist als Restore-Quelle wertlos — dann stattdessen aus Hetzner-Borg restaurieren.
Automatischer Pull
pull-critical-backups.ps1 zieht per Robocopy vom Unraid-SMB-Share:
\\192.168.178.58\backups\borg\dumps\latest→borg-dumps\latest\\\192.168.178.58\backups\git-bundles\gitea→git-bundles\gitea\
Der Windows Scheduled Task KalliLab H Drive Nearline Pull laeuft seit
2026-05-28 taeglich 05:30. Das Script kopiert bewusst nicht mit /MIR und
loescht nichts auf H:/; alte Artefakte werden nur nach manueller Sichtpruefung
entfernt.
Wichtig — Task-LogonType (kein S4U!): Der Task darf nicht mit
S4Ulaufen ("Unabhaengig von der Benutzeranmeldung ausfuehren" mit angehaktem "Kennwort nicht speichern"). S4U-Laeufe haben keine Netzwerk-Anmelde- informationen und erreichen den authentifizierten SMB-Share\\192.168.178.58\backupsnicht -> jeder geplante Lauf bricht still mit Exitcode 1 ab, ohne Report. Genau das passierte 2026-06-19 bis 2026-06-21 (Spiegel still veraltet).Behoben am 2026-06-21: Task auf "Nur ausfuehren, wenn der Benutzer angemeldet ist" (LogonType
Interactive) umgestellt. Das braucht kein gespeichertes Passwort und funktioniert, weilmichider dauerhaft angemeldete Konsolen-User ist (gesperrter Bildschirm zaehlt als angemeldet). Per Planer ausgeloest und mit Ergebnis0x0verifiziert. Alternative waere LogonTypePassword(gespeichertes Passwort), erfordert aber das Windows-Passwort.
Aufruf zum Testen:
powershell.exe -NoProfile -ExecutionPolicy Bypass -File G:\Gitea_Clone\homelab-infra\ops\h-drive-nearline\pull-critical-backups.ps1 -WhatIf
Das Script schließt bewusst aus:
unraid-flash-config.tar.gz(0600 root:root, nicht per SMB zugänglich → Restore aus Hetzner-Borg)- Migration-/Cutover-Verzeichnisse (
immich-vectorchord-*,pg18-major-*,redis8-*etc.)
Externer Dead-Man's-Switch
Der Pull lief ~2026-06-04 bis 2026-06-18 still gestoppt, ohne dass etwas Alarm
schlug (Scheduled Task fehlte; Prometheus auf Unraid sieht den baerchen-Pull
nicht). Gegenmittel: ein externer Heartbeat. pull-critical-backups.ps1 pingt am
Lauf-Anfang /start, am Ende den Erfolg und im Fehlerfall /fail. Bleibt der
Erfolgs-Ping aus, alarmiert der externe Dienst von aussen.
Die Integration ist endpoint-agnostisch: jede Healthchecks-kompatible URL funktioniert (Healthchecks.io-Cloud oder self-hosted). Ist keine URL gesetzt, ist der Switch ein No-Op und der Pull laeuft unveraendert weiter.
URL-Quelle (in dieser Reihenfolge):
- Parameter
-HealthchecksUrl - ENV
HEALTHCHECKS_NEARLINE_URL - Datei
%USERPROFILE%\.kallilab\healthchecks-nearline-url.txt
Die Ping-URL ist eine Capability-URL -> wie ein Secret behandeln, nie ins Repo
(siehe docs/SECRETS_MAP.md).
Operator-Setup (einmalig)
- Check anlegen (Healthchecks.io oder self-hosted): Period = 1 Tag, Grace z. B. 2-3 h passend zum taeglichen 05:30-Task. Ping-URL kopieren.
- Auf baerchen die URL hinterlegen, z. B. als Datei:
(alternativ als persistente User-Umgebungsvariable
New-Item -ItemType Directory -Force -Path "$HOME\.kallilab" | Out-Null Set-Content -LiteralPath "$HOME\.kallilab\healthchecks-nearline-url.txt" -Value "https://hc-ping.com/<uuid>" -NoNewlineHEALTHCHECKS_NEARLINE_URL.) - Testlauf:
pull-critical-backups.ps1ausfuehren; im Healthchecks-Dashboard muss ein "success"-Ping ankommen.
Borg-Pre-Hook-Pendant
Den gleichen Switch gibt es host-seitig in ops/borg-ui/scripts/pre-borg.sh.
URL dort via ENV HEALTHCHECKS_BORG_URL oder Datei
/mnt/user/appdata/secrets/healthchecks_borg_url (chmod 600), bewusst als
eigener Check (getrennter Heartbeat fuer die Unraid-Backup-Vorpruefung).
_dr-kit
Enthält offline hinterlegte Schlüssel und Secrets für den DR-Fall:
dr-hetzner/dr-hetzner.pub— SSH-Key für Hetzner Storage Boxdr-readonly/dr-readonly.pub— Read-only Deploy-KeyKOmodo Secrets.txt— Komodo Stack ENV-Offline-Dokumentation
Diese Dateien sind manuell zu pflegen und nicht vom Pull-Script verwaltet.
Archiv-Ordner
Temporäre Notfall-Artefakte verbleiben als _archiv-*-Ordner bis zur bewussten
Löschentscheidung:
| Ordner | Inhalt | Anlassdatum |
|---|---|---|
kallilab-recovery\_archiv-nvme-crash-image-2026-05-14\ |
nvme0n1 Disk-Image (1863 GB) + Crash-Runbooks aus dem Mai-2026-Ausfall | 2026-05-14 |
Aufräum-Historie
| Datum | Aktion |
|---|---|
| 2026-06-10 | OneDrive - Stroetmann Group\ gelöscht (leer) |
| 2026-06-10 | SSH-Keys + Secrets aus nearline-Root in _dr-kit\ verschoben |
| 2026-06-10 | Migration-Artefakt-Verzeichnisse in borg-dumps\latest\ gelöscht (immich-vectorchord-, pg18-major-, redis8-, nextcloud-redis-pre-redis8-, shared-redis-pre-redis8-*) |
| 2026-06-10 | Pre-major-prod-Dumps gelöscht (PG17→PG18-Migration abgeschlossen) |
| 2026-06-10 | kallilab-recovery\2026-05-15\ gelöscht (DNS-Restore-Reste) |
| 2026-06-10 | kallilab-recovery\2026-05-14\ → _archiv-nvme-crash-image-2026-05-14\ umbenannt |
| 2026-06-10 | kallilab-recovery\disk1-phase2-2026-05-23\ gelöscht (1677 GB Media-Share-Kopie; Unraid-Share verifiziert vollständig) |
Offene Punkte
Windows-Neuaufsetzen-Backup\(48 GB): nach vollständiger Rückspielung auf D:\ löschen_archiv-nvme-crash-image-2026-05-14\(1863 GB): löschen sobald sicher, dass nichts mehr aus dem alten System benötigt wird- Log-Rotation für
_logs\und_reports\: manuell oder per Script, Empfehlung 30 Tage