Tipy

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.

12. 10. 2026 · 4 min čtení

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:

  1. Na testovacím serveru nebo v kontejneru obnovte databázi a soubory.
  2. Spusťte aplikaci proti obnoveným datům.
  3. Ověřte, že data jsou úplná a aktuální (počet záznamů, poslední objednávka).
  4. Změřte čas obnovy. Pokud trvá 6 hodin a firma vydrží jen hodinu výpadku, máte problém.
  5. 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.