Zálohy a obnova pro vývojáře – databáze, soubory a test obnovy
Pravidlo 3-2-1, zálohy PostgreSQL a MySQL, restic pro soubory, automatizace přes cron a hlavně pravidelný test obnovy. Praktický návod s příkazy.
Git není záloha databáze. RAID není záloha. Snapshot na stejném disku není záloha. A záloha, kterou jste nikdy nezkusili obnovit, je jen naděje. Tento návod ukazuje, jak si jako vývojář nastavit zálohy, které vás opravdu zachrání.
Pravidlo 3-2-1
- 3 kopie dat (produkce + 2 zálohy),
- na 2 různých typech úložiště,
- 1 kopie mimo hlavní lokalitu (jiné datacentrum, jiný poskytovatel).
Moderní rozšíření je 3-2-1-1-0: jedna kopie neměnná nebo offline (ochrana proti ransomwaru a omylu, který smaže i zálohy) a 0 chyb při ověření obnovy.
Co zálohovat
| Data | Jak | Poznámka |
|---|---|---|
| Kód | Git na vzdáleném serveru (GitHub, GitLab) | Už to máte, ale ověřte, že je pushnuté vše |
| Databáze | Dump nebo fyzická záloha | Nejdůležitější |
| Nahrané soubory uživatelů | restic, borg, rsync | Často zapomínané |
| Konfigurace serveru | Git (infrastruktura jako kód), nebo záloha /etc |
Nginx, systemd unity, cron |
| Tajemství | Správce hesel / trezor | Bez nich obnova nefunguje |
Zálohy databáze
PostgreSQL
# Logická záloha v custom formátu (komprimovaná, umožňuje selektivní obnovu)
pg_dump -Fc -U app -h localhost app > /backup/app_$(date +%F).dump
# Obnova do nové databáze
createdb -U postgres app_restore
pg_restore -U postgres -d app_restore --no-owner /backup/app_2026-10-12.dump
Pro velké databáze a obnovu k libovolnému okamžiku (point-in-time recovery) sáhněte po nástrojích pgBackRest nebo Barman, které kombinují fyzické zálohy a archivaci WAL.
MySQL / MariaDB
mysqldump --single-transaction --routines --triggers -u app -p app \
| gzip > /backup/app_$(date +%F).sql.gz
# Obnova
gunzip < /backup/app_2026-10-12.sql.gz | mysql -u app -p app_restore
--single-transaction zajistí konzistentní snímek u InnoDB tabulek bez zamykání. Heslo nepředávejte v příkazu (-pHeslo je vidět v seznamu procesů) – uložte ho do ~/.my.cnf s právy 600.
SQLite
Kopírovat soubor za běhu aplikace je riskantní. Použijte vestavěný příkaz:
sqlite3 app.db ".backup '/backup/app_$(date +%F).db'"
Zálohy souborů s resticem
restic šifruje, deduplikuje a umí ukládat lokálně, přes SFTP i do S3 kompatibilních úložišť.
# Jednorázová inicializace repozitáře
export RESTIC_REPOSITORY=sftp:[email protected]:/srv/restic/app
export RESTIC_PASSWORD_FILE=/root/.restic-pass
restic init
# Záloha
restic backup /var/www/app/uploads /etc/nginx /backup
# Udržování: 7 denních, 4 týdenní, 6 měsíčních
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
# Kontrola integrity
restic check
Heslo k repozitáři uložte i jinam než na server (správce hesel). Bez něj jsou zálohy nečitelné – to je smysl šifrování.
Automatizace
Skript /usr/local/bin/backup.sh:
#!/usr/bin/env bash
set -euo pipefail
export RESTIC_REPOSITORY=sftp:[email protected]:/srv/restic/app
export RESTIC_PASSWORD_FILE=/root/.restic-pass
pg_dump -Fc -U app app > /backup/app.dump
restic backup /var/www/app/uploads /backup --tag nightly
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
set -euo pipefail zajistí, že skript při chybě skončí, místo aby tiše pokračoval. Spouštění přes cron (crontab -e jako root):
30 3 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1
Nebo přes systemd timer, který nabízí lepší logování (journalctl -u backup).
Hlídejte, že záloha proběhla
Nejhorší scénář: záloha tři měsíce tiše nefunguje. Řešení – na konci skriptu pošlete „ping“ do monitorovací služby typu dead man’s switch (např. Healthchecks.io, Uptime Kuma s push monitorem). Pokud ping nepřijde, dostanete upozornění.
curl -fsS -m 10 --retry 3 https://hc-ping.com/VAS-UUID > /dev/null
Test obnovy: nejdůležitější krok
Naplánujte si pravidelně (třeba jednou měsíčně) skutečnou obnovu:
- Na testovacím serveru nebo v kontejneru obnovte databázi a soubory.
- Spusťte aplikaci proti obnoveným datům.
- Ověřte, že data jsou úplná a aktuální (počet záznamů, poslední objednávka).
- Změřte čas obnovy. Pokud trvá 6 hodin a firma vydrží jen hodinu výpadku, máte problém.
- Postup zapište jako runbook – ve stresu po havárii nikdo nebude improvizovat dobře.
# Obnova souborů z resticu do dočasné složky
restic restore latest --target /tmp/restore-test
Dvě čísla, která byste měli znát:
- RPO (Recovery Point Objective) – kolik dat smíte ztratit. Denní záloha = až 24 hodin.
- RTO (Recovery Time Objective) – jak rychle musíte být zpět online.
Časté chyby
- Zálohy na stejném serveru jako produkce.
- Záloha pod stejným účtem, který může zálohy i mazat (útočník nebo chybný skript smaže obojí). Pomůže append-only režim úložiště.
- Chybějící záloha nahraných souborů nebo
.env. - Žádná kontrola, zda cron vůbec běží.
- Nikdy nevyzkoušená obnova.
Pokud spravujete VPS, můžete zálohovací skript nastavit s pomocí ColdHost AI v režimu Server a DevOps – asistent navrhne příkazy, vy každý před spuštěním schválíte a výstup se vrátí zpět k analýze.