Co dokładnie warto kopiować
Lista tego, co naprawdę trzeba zabezpieczyć na VPS, czego kopiować nie ma sensu i jak wyeksportować bazy danych, żeby kopia faktycznie działała.
Zaktualizowano 23 sierpnia 2026
Nie robimy automatycznych kopii zapasowych twojej maszyny: w panelu też nie ma snapshotów stanu, a reinstalacja systemu całkowicie czyści dysk. Oznacza to, że kopie zapasowe są w całości twoją odpowiedzialnością i musisz zacząć już pierwszego dnia, a nie po stracie.
Co musisz zabezpieczyć
- Dane aplikacji — wolumeny Docker, katalogi stron, pliki wgrywane przez użytkowników.
- Zrzuty baz danych — konkretnie zrzuty, a nie pliki działającej bazy (więcej o tym niżej).
- Konfigurację —
/etc/nginx,/etc/caddy, unity systemd, plikicompose.yamli.env, reguły firewalla. - Certyfikaty i klucze —
/etc/letsencrypt, klucze aplikacji, klucze DKIM serwera pocztowego. - Zadania zaplanowane —
crontab -l > /root/crontab.txtprzed zrobieniem kopii, inaczej odtworzysz wszystko oprócz harmonogramu. - Listę zainstalowanych pakietów —
dpkg --get-selections > /root/packages.txt. Zajmuje kilobajty, oszczędza godziny.
Czego nie musisz zabezpieczać
System, pakiety i obrazy Docker odtwarzasz przez reinstalację i uruchomienie poleceń — nie są warte miejsca i czasu. Nie rób kopii /proc, /sys, /dev, /var/lib/docker w całości, katalogów cache ani plików swap.
Rozsądna zasada: kopia zapasowa powinna zawierać wszystko, czego nie ma w internecie i czego nie odtworzysz z instrukcji.
Bazy danych
Nie możesz kopiować plików działającej bazy: dostaniesz snapshot zrobiony w trakcie zapisu, który może się nie otworzyć. Właściwy sposób to zrzut przy użyciu narzędzi samej bazy.
docker compose exec -T db pg_dump -U postgres app | gzip > /backup/app-$(date +%F).sql.gz
docker compose exec -T db mysqldump -u root -p"$MYSQL_ROOT_PASSWORD" --single-transaction app | gzip > /backup/app-$(date +%F).sql.gz
sqlite3 /data/app.db ".backup '/backup/app-$(date +%F).db'"
W przypadku PostgreSQL i MySQL nie musisz zatrzymywać usługi. Dla SQLite użyj .backup, a nie cp: kopiowanie pliku w trakcie działania daje uszkodzoną bazę.
Kopia zapasowa, z której nigdy nie odtworzyłeś danych, nie liczy się jako kopia zapasowa. Przetestuj ją na pustej maszynie albo w osobnym kontenerze — zobacz próbne odtworzenie.
Przykład kompletnego zestawu
#!/bin/bash
set -euo pipefail
DEST=/backup/$(date +%F)
mkdir -p "$DEST"
docker compose -f /opt/myapp/compose.yaml exec -T db pg_dump -U postgres app | gzip > "$DEST/db.sql.gz"
tar czf "$DEST/etc.tar.gz" /etc/nginx /etc/letsencrypt /opt/myapp/compose.yaml /opt/myapp/.env
tar czf "$DEST/uploads.tar.gz" /var/www/uploads
crontab -l > "$DEST/crontab.txt"
dpkg --get-selections > "$DEST/packages.txt"
Umieść skrypt w /usr/local/bin/backup.sh, nadaj mu uprawnienia przez chmod 700 i dodaj do harmonogramu. Potem musisz wysłać kopię w inne miejsce — plik obok twoich danych przed niczym cię nie chroni.
Jak długo przechowywać
Zasada „3-2-1” w uproszczonej formie: co najmniej dwie kopie, co najmniej jedna poza tą maszyną. Jeśli chodzi o przechowywanie, wystarczy siedem dziennych, cztery tygodniowe i trzy miesięczne — to dość, żeby cofnąć się do stanu sprzed cichej awarii, której nie zauważyłeś od razu.
Zaplanuj miejsce z wyprzedzeniem: VDS-1 ma dysk 40 GB i po prostu nie ma na nim gdzie trzymać historii kopii — zobacz miejsce na dysku.
Częste błędy
- Kopia leży na tej samej maszynie. Reinstalacja, utrata dostępu, pomyłka z
rm -rf— i kopia znika razem z danymi. - Zapomniałeś o
.env. Masz dane, ale hasła i klucze do nich przepadły. - Kopiowanie wolumenu bazy w trakcie działania. Odtworzenie kończy się na uszkodzonym pliku. Tylko zrzuty.
- Nikt nie wie, że kopia przestała powstawać. Skonfiguruj sprawdzanie przez push w Uptime Kuma: skrypt pinguje adres po sukcesie, a dzień ciszy wywołuje alert.