Backup, którego nie masz, nie istnieje

Każdy administrator wie, że backupy są ważne. Mimo to zaskakująco wiele serwerów — szczególnie małych, obsługujących kilka stron firmowych — nie ma żadnej strategii tworzenia kopii zapasowych. Problemy pojawiają się nagle: uszkodzenie dysku, błędna aktualizacja, atak ransomware, przypadkowe rm -rf w złym katalogu. Bez backupu odzyskanie danych bywa niemożliwe lub kosztowne.

Dobra strategia backupów nie musi być skomplikowana ani droga. Wymaga jednak systematyczności i regularnego testowania.

Reguła 3-2-1

Podstawą każdej strategii backupów jest sprawdzona reguła 3-2-1:

  • 3 kopie danych (oryginał + 2 kopie zapasowe)
  • 2 różne nośniki (np. dysk serwera + storage zewnętrzny)
  • 1 kopia w innej lokalizacji (offsite)

Dla małego serwera VPS realizacja tej reguły może wyglądać następująco:

  1. Oryginał — dane na serwerze produkcyjnym
  2. Kopia lokalna — snapshot lub backup na tym samym serwerze (szybkie odtworzenie po drobnych błędach)
  3. Kopia offsite — backup na zewnętrznym storage (ochrona przed awarią serwera)

Co backupować?

Nie wszystkie dane na serwerze wymagają backupu. Kluczowe jest zidentyfikowanie tego, co jest nieodtwarzalne:

  • Bazy danych — dane użytkowników, treści, konfiguracje
  • Pliki przesyłane przez użytkowników — zdjęcia, dokumenty, załączniki
  • Pliki konfiguracyjne — nginx, docker-compose, .env, certyfikaty SSL
  • Dane specyficzne dla aplikacji — logi transakcyjne, dane sesji

Nie trzeba backupować:

  • Kodu aplikacji (powinien być w repozytorium Git)
  • Obrazów Docker (można zbudować ponownie)
  • Cache i plików tymczasowych
  • Logów systemowych (chyba że wymagane prawnie)

Backup bazy danych

PostgreSQL

#!/bin/bash
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="/home/backups/db"

# Dump bazy danych
pg_dump -h localhost -U appuser -d myapp -F c -f "$BACKUP_DIR/myapp_$TIMESTAMP.dump"

# Usunięcie backupów starszych niż 30 dni
find "$BACKUP_DIR" -name "*.dump" -mtime +30 -delete

Opcja -F c tworzy backup w formacie custom, który obsługuje selektywne odtwarzanie tabel i kompresję.

Dla baz w kontenerach Docker:

docker exec postgres-container pg_dump -U appuser -d myapp -F c > "$BACKUP_DIR/myapp_$TIMESTAMP.dump"

MySQL

mysqldump -u root -p --all-databases --single-transaction | gzip > "$BACKUP_DIR/all_$TIMESTAMP.sql.gz"

Opcja --single-transaction zapewnia spójny backup bez blokowania tabel (dla InnoDB).

Backup plików

rsync — przyrostowe kopie

rsync to podstawowe narzędzie do backupu plików, tworzące przyrostowe kopie (kopiuje tylko zmienione pliki):

#!/bin/bash
TIMESTAMP=$(date +%Y%m%d)
SOURCE="/home/www"
DEST="/home/backups/files"

rsync -avz --delete \
  --exclude='.git' \
  --exclude='node_modules' \
  --exclude='*.log' \
  "$SOURCE/" "$DEST/latest/"

# Tworzenie snapshotu z hardlinkami (oszczędność miejsca)
cp -al "$DEST/latest/" "$DEST/$TIMESTAMP/"

Opcja cp -al tworzy kopię z hardlinkami — pliki, które się nie zmieniły, nie zajmują dodatkowego miejsca na dysku.

restic — nowoczesne backupy

restic to narzędzie nowej generacji, oferujące szyfrowanie, deduplikację i wsparcie dla wielu backendów storage:

# Inicjalizacja repozytorium (jednorazowo)
restic init --repo s3:s3.amazonaws.com/my-backups

# Tworzenie backupu
restic backup /home/www /etc/nginx --repo s3:s3.amazonaws.com/my-backups

# Retencja — zachowanie określonej liczby backupów
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune

restic automatycznie deduplikuje dane — jeśli ten sam plik istnieje w wielu backupach, przechowywany jest tylko raz. Wsparcie dla S3, SFTP, Backblaze B2 i innych backendów sprawia, że łatwo realizować kopie offsite.

Przechowywanie offsite

Kopia offsite chroni przed scenariuszami, w których cały serwer jest niedostępny:

  • Object storage (S3, Backblaze B2) — najtańsza opcja dla backupów. Backblaze B2 kosztuje $0.005/GB/miesiąc, czyli 50 GB backupów to około $0.25 miesięcznie.
  • Drugi serwer VPS — backup przez rsync/SFTP na drugi serwer w innym centrum danych.
  • Usługa backupu hostingodawcy — wiele firm hostingowych oferuje backup storage za niewielką opłatą.

Przesyłanie offsite za pomocą rclone:

# Konfiguracja (jednorazowo)
rclone config  # interaktywna konfiguracja providera

# Synchronizacja backupów
rclone sync /home/backups remote:server-backups --transfers=4

Automatyzacja z cron

Wszystkie skrypty backupowe powinny być uruchamiane automatycznie:

# Backup bazy danych — codziennie o 3:00
0 3 * * * /home/scripts/backup-db.sh >> /var/log/backup-db.log 2>&1

# Backup plików — codziennie o 4:00
0 4 * * * /home/scripts/backup-files.sh >> /var/log/backup-files.log 2>&1

# Przesyłanie offsite — codziennie o 5:00
0 5 * * * /home/scripts/backup-offsite.sh >> /var/log/backup-offsite.log 2>&1

Ważne: dodaj powiadomienie o niepowodzeniu backupu. Backup, który cicho przestaje działać, jest gorszy niż brak backupu — daje fałszywe poczucie bezpieczeństwa.

Testowanie odtwarzania

Najważniejsza zasada backupów: backup, którego nie testowałeś, nie istnieje. Regularnie (co najmniej raz na kwartał) przeprowadzaj test odtwarzania:

  1. Pobierz backup z offsite storage
  2. Odtwórz bazę danych na testowym serwerze
  3. Zweryfikuj, że dane są kompletne i spójne
  4. Zmierz czas odtwarzania — czy jest akceptowalny?

Warto udokumentować procedurę odtwarzania krok po kroku. W momencie awarii nie jest to czas na eksperymenty i czytanie dokumentacji.

Podsumowanie

Strategia backupów dla małego serwera sprowadza się do kilku elementów: identyfikacja krytycznych danych, automatyczne skrypty uruchamiane przez cron, kopia offsite na tanim object storage i regularne testowanie odtwarzania. Koszt takiego rozwiązania to kilka godzin konfiguracji i kilka złotych miesięcznie za storage. Koszt braku backupu w momencie awarii — nieporównywalnie wyższy.