Backup, który sam mówi, czy działa: Kopia + n8n jako data observability w homelabie
Backup, który sam mówi, czy działa
Przez rok mój homelab nie miał żadnego backupu. Dwie maszyny wirtualne z Dockerem, kilkadziesiąt kontenerów, NAS z ZFS-em — i zero kopii poza samą redundancją dysków. Wiedziałem, że to źle. Wiedziałem też, dlaczego nic z tym nie robię: nie bałem się braku backupu. Bałem się backupu, który wygląda, jakby działał.
W pracy zajmuję się Data Governance i jakością danych. Tam podstawową zasadą jest: jeśli nie mierzysz, to nie wiesz. Ten artykuł to case study przeniesienia tej zasady na własny sprzęt — od pierwszego snapshotu Kopii po workflow w n8n, który co rano ocenia 14 źródeł backupu i mówi, które z nich są nieaktualne, niekompletne lub uszkodzone.
Problem: 3-2-1 to polityka, nie kontrola
Reguła 3-2-1 (trzy kopie, dwa nośniki, jedna poza domem) jest wszędzie. Ale to polityka — mówi, jak ma być. Nie mówi, jak sprawdzić, czy jest.
W praktyce backupy w domu psują się cicho:
- cron działa, ale snapshot ma 0 plików, bo katalog źródłowy odmontował się po restarcie,
- klient backupu nie łączy się z serwerem od tygodnia, a jedyny log leży na maszynie, na którą nikt nie patrzy,
- baza w kontenerze jest kopiowana „na gorąco” i pliki są niespójne,
- off-site synchronizuje się, ale z błędem
rc=1na końcu, którego nikt nie czyta.
Każdy z tych przypadków spełnia 3-2-1 na papierze. Potrzebowałem więc dwóch rzeczy: sensownej architektury backupu i niezależnej warstwy, która codziennie zweryfikuje, czy ta architektura robi to, co obiecuje.
Architektura: Kopia na NAS-ie
Wybrałem Kopię — open-source, deduplikacja, kompresja zstd, szyfrowanie po stronie klienta, tryb serwera z użytkownikami i API. Serwer stoi jako kontener na NAS-ie (TrueNAS), repozytorium leży na puli ZFS.
flowchart LR
subgraph NAS
ZFS[dataset z danymi aplikacji] -->|snapshot ZFS 02:55| SNAP[mount read-only]
SNAP -->|03:00| KS[Kopia server]
DOCS[dokumenty, zdjęcia, eksporty] -->|03:10–03:30| KS
KS -->|05:00 sync-to rclone| GD[(off-site: Google Drive)]
end
subgraph VM z Dockerem x2
DUMP[pg_dumpall / mariadb-dump 02:30] --> KC[klient Kopii 03:00 / 03:15]
VOL[wolumeny Dockera, configi] --> KC
end
KC -->|HTTPS + fingerprint| KS
PVE[Proxmox vzdump 02:00] -->|NFS| NAS
Cztery warstwy, każda z innym celem:
| Warstwa | Co chroni | Narzędzie | Kiedy |
|---|---|---|---|
| Snapshot ZFS + Kopia | dane aplikacji na NAS-ie (spójny obraz) | zfs snapshot → Kopia | 02:55 → 03:00 |
| Klienci Kopii na VM | wolumeny Dockera, configi, zrzuty baz | Kopia CLI, cron | 02:30 → 03:00/03:15 |
| Off-site | całe repozytorium Kopii | kopia repository sync-to rclone | 05:00 |
| vzdump | pełne VM (odtworzenie po padzie dysku) | Proxmox → NFS na NAS | 02:00 |
Retencja jako polityka Kopii: 7 dziennych, 4 tygodniowe, 6 miesięcznych; zdjęcia (250 GB) skromniej — 3/2/3 i bez kompresji, bo JPEG-ów i tak nie ściśniesz.
Spójność: snapshot ZFS zamiast „kopiuj na żywo”
Kontenery na NAS-ie piszą do plików cały czas. Kopiowanie takiego katalogu daje obraz, w którym połowa plików jest z 03:00, a druga z 03:04. Rozwiązanie: cron o 02:55 robi snapshot ZFS datasetu i montuje go read-only w stałym miejscu; Kopia o 03:00 czyta już tylko zamrożony obraz.
Dwie pułapki, których nie znajdziesz w dokumentacji:
-
.zfs/snapshotnie działa z wnętrza kontenera — automount ZFS nie przechodzi przez mount namespace Dockera i kończy się błędemToo many levels of symbolic links. Stąd jawnymount -t zfs -o rona hoście. - Bind mount do kontenera musi wskazywać katalog nadrzędny, nie sam punkt montowania snapshotu. Inaczej kontener trzyma referencję do starego montu i
zfs destroyzwracadataset is busy. Do tegorslave, żeby kontener widział podmianę montu bez restartu.
Bazy danych: zrzut jest źródłem prawdy
Wolumeny Dockera na VM leżą na ext4 — nie ma snapshotów. Katalog pg_data skopiowany w trakcie zapisu jest bezwartościowy. Dlatego przed backupem chodzi generyczny skrypt: iteruje po kontenerach, znajduje te z montem /var/lib/postgresql/data lub /var/lib/mysql, robi pg_dumpall / mariadb-dump --all-databases, pakuje zstd do jednego katalogu. Szesnaście baz na dwóch VM, poniżej minuty łącznie.
To jest decyzja architektoniczna, nie techniczna: backup katalogu bazy to artefakt pomocniczy, zrzut logiczny to źródło prawdy. Zapisałem to wprost w notatkach, żeby za pół roku nie kusiło mnie „przecież katalog też jest w Kopii”.
Off-site bez płacenia za drugi NAS
Kopia ma wbudowane repository sync-to, a obraz kontenera zawiera rclone. Jeden skrypt, jeden cron o 05:00, cel: Google Drive z pakietu, który i tak miałem. 70 GB repozytorium (po deduplikacji i kompresji) synchronizuje się przyrostowo w kilka minut; pierwszy pełny sync zdjęć zajął noc. Jedyny warunek, którego przestrzegam: po pierwszym syncu podłączyłem się do kopii off-site z innego komputera i odpaliłem kopia snapshot verify. Kopia sama ostrzega, że backend rclone jest „not actively tested” — więc testuję ja.
Strażnik: data observability dla backupów
Tu zaczyna się część, dla której powstał ten wpis. Architektura powyżej ma pięć cronów na trzech maszynach i cztery różne logi. Nikt tego nie będzie czytał codziennie. Potrzebowałem jednego punktu, który o 04:00 zada każdemu źródłu backupu to samo pytanie: czy jesteś świeży, kompletny i bez błędów?
Zbudowałem to w n8n, które i tak stoi w homelabie. Workflow „Strażnik backupów”:
- Pobiera stan z API Kopii (
GET /api/v1/sources) — jeden request daje wszystkie źródła ze wszystkich hostów: ostatni snapshot, rozmiar, liczbę plików, liczbę błędów. - Ocenia każde źródło progami zdefiniowanymi per źródło, nie globalnie. Dane aplikacji: wiek ≤ 26 h, rozmiar ≥ 1 GB, pliki ≥ 5000, błędy = 0. Zdjęcia: ≥ 200 GB, ≥ 10 k plików. Backup komputera, który robi się raz w tygodniu: wiek ≤ 192 h.
- Sprawdza to, czego nie ma w Kopii: backupy VM przez API Proxmoxa (ostatni plik ≤ 30 h, ≥ 1 GB), replikację ZFS i alerty TrueNAS przez webhooki push z NAS-a, wynik off-site z kodu wyjścia skryptu.
- Brak źródła na liście = alarm krytyczny. To najważniejsza reguła. Backup, który przestał istnieć, nie zgłosi się sam.
- Wysyła wynik do jednego dyspozytora powiadomień (osobny workflow n8n), który normalizuje severity, deduplikuje po kluczu (
kopia:<host>:<ścieżka>) i kieruje: krytyczne na Discord#alerts+ push na telefon, informacyjne na#backups.
Efekt: rano widzę czternaście zielonych linijek albo jedną czerwoną z konkretem. Nic pomiędzy.
Pułapki, które Strażnik wyłapał w pierwszym tygodniu
- Strefa czasowa NAS-a była ustawiona na US Pacific. Crony NAS-a (snapshot ZFS 02:55, sync 05:00) chodziły 9 godzin później niż crony w kontenerach. Kopia przez kilka dni kopiowała snapshot sprzed 15 godzin. Backup „działał” — po prostu był stary. Wyszło dopiero, gdy porównałem znaczniki czasu w progu świeżości.
-
stats.fileCountw API Kopii zwraca 0, gdy snapshot korzysta z cache’a. Pierwszej nocy Strażnik krzyknął, że backup ma zero plików. Liczba wsummary.filesbyła poprawna. Próg musi patrzeć na właściwe pole — lekcja znana każdemu, kto pisał reguły DQ na źle udokumentowanym schemacie. - Token API Proxmoxa z rolą „tylko audyt” zwracał pustą listę backupów, nie błąd. Strażnik raportował „brak backupu VM”, mimo że pliki leżały na NAS-ie. Proxmox ukrywa backupy bez uprawnień
VM.Backupna konkretnej VM. Fałszywy alarm krytyczny jest gorszy niż brak alarmu — po tygodniu przestajesz czytać. - Nowe źródła z klientów pojawiają się w API serwera dopiero po restarcie kontenera. Trzy dni Strażnik nie widział połowy backupów, bo lista była zbuforowana.
Test odtworzenia, bo inaczej to nie backup
Zanim uznałem system za wdrożony: qmrestore całej VM z NFS-a do nowego ID (128 GB, 37 minut), start, sprawdzenie konfiguracji, qm destroy. Osobno odtworzenie pojedynczego katalogu z Kopii do /tmp i porównanie sum. Oba w notatkach z datą — bo za rok będę chciał wiedzieć, kiedy ostatnio to sprawdzałem.
Co z tego dla Data Governance
Nie pisałem tego jako ćwiczenia z governance. Ale kiedy spojrzałem na gotowy system, zobaczyłem w nim jeden do jednego rzeczy, które robię zawodowo.
Progi Strażnika to wymiary jakości danych. Wiek snapshotu = timeliness. Minimalny rozmiar i liczba plików = completeness. Zero błędów w snapshocie = validity. Zgodność liczby źródeł z listą oczekiwanych = consistency między „co powinno być” a „co jest”. Pisałem o sześciu wymiarach DQ pół roku temu; tu są te same wymiary zastosowane do metadanych backupu.
Polityka bez kontroli to dokument. Retencja 7/4/6 w Kopii to polityka. Strażnik to kontrola. W firmie nazwałbym to data quality rule podpiętą pod data policy — i dokładnie tak samo jak w firmie, bez kontroli polityka rozjeżdża się cicho (patrz: strefa czasowa).
Progi per źródło, nie globalne. Reguła „backup musi mieć ≥ 1 GB” jest bez sensu dla eksportu dokumentów (400 MB) i dla zdjęć (250 GB). W DQ to banał: progi kompletności ustala właściciel danych, nie zespół platformy. W homelabie właścicielem jestem ja, ale zasada jest ta sama — próg wynika ze znajomości danych.
Brak danych to najgroźniejszy stan danych. Najważniejsza reguła Strażnika — „źródła nie ma na liście = crit” — to odpowiednik kontroli „tabela nie została załadowana”, którą wiele zespołów pomija, bo sprawdzają jakość tylko tego, co przyszło.
Fałszywe alarmy zabijają kontrolę. Trzy z czterech pułapek powyżej to fałszywe pozytywy. Każdy z nich obniżał zaufanie do całego systemu. W governance mówi się o alert fatigue; w domu nazywa się to „wyciszyłem kanał na Discordzie”.
Źródło prawdy trzeba nazwać. Zrzut logiczny bazy, nie katalog z plikami. Zapisane wprost. To jest system of record w skali jednego człowieka.
Nie twierdzę, że homelab uczy governance lepiej niż praca. Twierdzę, że te same zasady działają w obu skalach — a w domu widzisz konsekwencje ich łamania w tydzień, nie w kwartał.
Co dalej
- Codzienny raport 14 zielonych linijek zamienić na zbiorczy poranny briefing; alarmy zostają natychmiastowe.
- Automatyczny test odtworzenia losowego pliku z off-site raz w miesiącu — zamiast polegać na tym, że przypomnę sobie za rok.
- Backup komputera domowego chodzi raz w tygodniu z progiem 192 h. To za rzadko dla dokumentów; do zmiany.
Jeśli masz w homelabie backup, którego nie sprawdza nic poza Tobą — zacznij od jednego pytania zadawanego codziennie automatycznie: ile godzin ma ostatni snapshot? Reszta progów dojdzie sama.
Enjoy Reading This Article?
Here are some more articles you might like to read next:
- Wymiary jakości danych: praktyczny przewodnik po Data Quality
- AI w Data Governance: szanse, wyzwania i praktyczne zastosowania
- Ataccama ONE — dlaczego wybrałem tę platformę do Data Governance
- Informatica jako narzędzie Data Governance: przegląd dla praktyków
- Standardy danych: czym są i dlaczego bez nich nie zbudujesz programu DG?
- Które normy ISO stosować w Data Governance? Praktyczny przegląd
- Wstęp do Data Governance
- Wstęp do Promptingu
- Historia wizualizacji danych
Subscribe to be notified of future articles: