Server & síť/Zálohy
Záloha, kterou jsem konečně obnovil.
Každou noc, šifrovaně, do cloudu a ještě jednou vedle. Jenže záloha, kterou jsem nikdy nezkusil vrátit, je jen pocit. Dnes jsem to zkusil.
K čemu to je
Kopie všeho, co bych neuměl vyrobit znovu
Na serveru běží skoro dvacet projektů: data aplikací, konfigurace a celý zdrojový kód. Většina z toho nikde jinde není. Kdyby disk umřel, nemám to odkud vzít.
Každou noc ve tři restic udělá snímek a pošle ho do Cloudflare R2. Hned potom se zrcadlí na Google Drive. Dvě úložiště, dvě firmy, a ani jedna nevidí, co je uvnitř.
Šifruje se totiž ještě na serveru, dřív než jediný bajt odejde ven. V cloudu leží jen nečitelné bloky. Klíč k obnově mám mimo server, na dvou místech.
Proč
Dva měsíce jsem zálohoval do prázdna
Na jaře jsem omylem smazal celý projekt. V klidu jsem šel do zálohy. Poslední snímek byl z konce března, dva měsíce starý.
Skript běžel v kontejneru na Alpine a na prvním řádku měl bash. Ten tam není. Cron ho každou noc spustil, dostal chybu a mlčel. Projekt jsem poskládal z jiné kopie. To štěstí jsem mít nemusel.
Od té doby se záloha hlídá a jednou za čas zkouší obnovit.
Jak to funguje
Snímek, dvě kopie a hlídač
- Každou noc ve tři jeden snímek. Restic ukládá jen změny od minula. Celý server je v cloudu čtvrt gigabajtu.
- Retence 7 denních, 4 týdenní, 3 měsíční. Starší snímky se samy promažou. Pozdě zjištěnou chybu dohledám tři měsíce zpátky.
- Druhá kopie na Google Drive. Po každé záloze se repozitář zrcadlí přes rclone. Stejné šifrování, stejný klíč, jiná firma.
- Hlídač píše do Telegramu. Snímek starší než 48 hodin znamená zprávu. Ticho už není důkaz, že je vše v pořádku.
Co jsem zjistil
Test obnovy v číslech
Obnova vzorku
236 MB, konfigurace DNS a hlavní compose soubor, včetně připojení do cloudu.
Rozdílů
Obnovené soubory proti těm, co právě běží. Bajt po bajtu stejné.
Snapshotů
Nejstarší z 31. března, nejnovější dnes ve tři ráno. Řada bez díry.
Komprese
O 62 % míň dat, než kolik jich zabírá na disku. Kód a konfigurace se komprimují dobře.
V cloudu
Z 10 GB, které Cloudflare dává zdarma. Za zálohu celého serveru neplatím nic.
Hranice pro poplach
Bez čerstvějšího snímku hlídač píše do Telegramu. Jarní výpadek by odhalil druhý den, ne za dva měsíce.
Co jsem se naučil
Tři věci, které mě to naučilo
Záloha bez testu obnovy není záloha
Dva měsíce jsem věřil, že jsem krytý. Věřit nestačí. Jednou za čas obnovit vzorek a porovnat, jinak je to jen pocit.
Tiché selhání je horší než hlasité
Cron, který spadne a mlčí, vypadá zvenku stejně jako ten, který funguje. Proto hlídač: když se záloha neozve, ozve se on. Dead-man's switch za pár řádků.
Co funguje na serveru, nemusí fungovat v kontejneru
Minimální obraz nemá bash a skript pro bash na něm nespustíš. Chyba zněla „not found“, přestože soubor existoval. První řádek skriptu si teď hlídám.
Pro AI agenta
Postav si to u sebe
Chceš si to postavit u sebe? Zkopíruj návod a dej ho svému AI agentovi, třeba Claude Code nebo Codexu. Je v něm cíl, postup krok za krokem, pasti, na které jsem narazil, a jak ověřit, že to funguje. Adresy ani hesla v něm nejsou, ty agent doplní s tebou.
Pro zvědavé
Technické detaily
Stack restic · R2 · rclone · Telegram
- Záloha
- restic v Docker kontejneru, cron denně ve 3:00, cíl Cloudflare R2 přes S3 API. Šifrování AES-256 na klientovi, deduplikace, komprese. Zálohují se data aplikací, konfigurace a celý zdrojový kód, bez závislostí a cache.
- Druhá kopie
restic copypřes rclone na Google Drive, stejný klíč. Cílový repozitář založený se stejnými parametry dělení bloků, aby fungovala deduplikace. Kopie je best effort s opakováním; když selže, hlavní zálohu to neshodí.- Retence
- 7 denních, 4 týdenní, 3 měsíční, prune po každé záloze. Kontejner musí mít pevné jméno hosta, jinak po každém rebuildu vznikne nová řada snímků a retence ji nepročistí.
- Hlídač
- Skript v cronu každé ráno se zeptá resticu na čas nejnovějšího snímku. Starší než 48 h, nebo restic vůbec neodpoví, znamená zprávu do Telegramu.
Jak obnovit postup, který jsem dnes prošel
Klíč k repozitáři vezmu z trezoru hesel (Bitwarden), ne ze serveru, protože při skutečné havárii server nemám. Připojím se k R2, nebo k Drive, když R2 nejede, a vypíšu snapshoty. Obnovím jen konkrétní cesty do dočasné složky, nikdy celý server přes živá data. Porovnám s tím, co běží, a teprve když všechno sedí, přepíšu. Dnes: 236 MB za 26 sekund, nula rozdílů.
Dál