Przejdź do treści
Aktualny kupon:10% zniżkiUżyj w zamówieniu

Kopie zapasowe VPS: co archiwizujemy my i jak zrobić własne

Jak działają automatyczne kopie zapasowe VPS w strefie klienta i kiedy je przywracać. Plus jak skonfigurować własne kopie plików i baz danych przez cron, rsync lub restic według zasady 3-2-1.

  • zaawansowany
  • ~25 min
  • Zaktualizowano 9.10.2026

Kopiami zapasowymi VPS zarządzamy my, a w strefie klienta możesz z nich przywrócić cały dysk. Dla pojedynczych plików, baz danych i kopii poza naszą infrastrukturą konfigurujesz własne kopie zapasowe. Pokażemy jedno i drugie.

Czego potrzebujesz

  • VPS w StormHost z Ubuntu 24.04 lub Debianem 13
  • Połączenie SSH jako root (poradnik)
  • Do kopii poza VPS drugi komputer lub serwer z dostępem SSH
  • Około 25 minut

Automatyczne kopie zapasowe StormHost#

Kopie zapasowe VPS tworzymy automatycznie. Znajdziesz je w strefie klienta: Moje usługi › Twój VPS › zakładka Kopie zapasowe.

  • Przy każdej kopii lista pokazuje Utworzono (data i godzina), Rozmiar i Magazyn, w którym jest przechowywana.
  • Kopii nie da się utworzyć ręcznie z strefy klienta. Przed ryzykowną zmianą (aktualizacja systemu, duża zmiana konfiguracji) zrób własną kopię zgodnie z resztą tego poradnika.
  • Jeśli widzisz „Jeden z magazynów kopii zapasowych teraz nie odpowiada — lista może być niepełna”, część kopii jest tymczasowo niedostępna. Spróbuj później albo skontaktuj się z nami.
  • Członek współdzielonej usługi widzi kopie tylko z uprawnieniem Kopie zapasowe i przywracanie.

Przywracanie całego VPS#

Przywracanie nadpisuje cały dysk

„Dane na dysku zostaną nieodwracalnie nadpisane kopią zapasową. VPS zostanie na czas przywracania wyłączony.” Wszystko utworzone na VPS po wykonaniu kopii (nowe zamówienia na stronie, zapisy gier, bazy danych, logi) przepada. Jeśli VPS zawiera coś takiego, najpierw to pobierz (SFTP, mariadb-dump).

  1. W zakładce Kopie zapasowe znajdź kopię po dacie w kolumnie Utworzono.
  2. Kliknij Przywróć.
  3. Przeczytaj ostrzeżenie i potwierdź je, przesuwając suwak („Przesuń, aby przywrócić”).
  4. Poczekaj na zakończenie. Podczas przywracania VPS jest wyłączony i zablokowany, a konsola się nie połączy.
  5. Po przywróceniu uruchom VPS (jeśli nie wystartuje sam) i sprawdź swoje usługi.

Pełne przywracanie czy pojedyncze pliki?#

SytuacjaCzego użyć
Zepsuty system, przejęty VPS, nieudana aktualizacjaPrzywróć cały VPS w zakładce Kopie zapasowe.
Usunięty lub nadpisany plik, zła edycja konfiguracjiWłasna kopia plików (niżej). Przywrócenie całego dysku cofnęłoby też wszystko inne.
Uszkodzone lub usunięte dane w bazie danychWłasna kopia bazy (eksport mariadb-dump).
Przenosiny na inny VPS lub do innego dostawcyWłasne kopie, najlepiej przechowywane poza VPS.

Zasada 3-⁠2-⁠1#

Sprawdzona zasada kopii zapasowych: 3 kopie danych, w 2 różnych miejscach lub typach nośników, z czego 1 poza główną infrastrukturą.

Dla VPS oznacza to:

  1. Dane na VPS (kopia pierwotna).
  2. Nasze automatyczne kopie zapasowe (druga kopia, poza Twoim VPS).
  3. Twoja własna kopia gdzie indziej: domowy NAS, inny serwer, chmura (trzecia kopia, poza naszą infrastrukturą).

Trzecia kopia chroni Cię nawet wtedy, gdy przywracanie w strefie klienta nie pomoże: potrzebujesz starszego stanu, jednego pliku albo chcesz się przenieść.

Co archiwizować#

Ścieżka / daneCo zawieraUwaga
/etcKonfiguracja systemu i usług (Nginx, SSH, cron, firewall).Mała; archiwizuj zawsze.
/home, /rootKatalogi domowe użytkowników, skrypty, klucze SSH./root/.ssh zawiera klucze prywatne, więc szyfruj kopię.
/var/wwwStrony WWW.
/opt, /srvAplikacje i dane, które tam instalujesz (na przykład projekty Docker Compose).
Bazy danychDane MariaDB/MySQL.Zawsze jako eksport (mariadb-dump), nigdy przez kopiowanie katalogu /var/lib/mysql w trakcie pracy; taka kopia byłaby niespójna.
Wolumeny DockeraDane kontenerów (/var/lib/docker/volumes).Bazy działające w kontenerach eksportuj; zobacz Docker i Docker Compose.
Dane serwerów gierŚwiaty, konfiguracja, pluginy.Katalog zależy od instalacji. Najlepiej zapisz serwer przed archiwizacją świata (save-all w Minecrafcie).
CrontabZaplanowane zadania.crontab -l > /root/crontab-zaloha.txt

Skrypt kopii zapasowej#

Skrypt codziennie eksportuje wszystkie bazy danych, pakuje ważne katalogi i usuwa kopie starsze niż 7 dni.

  1. Utwórz plik skryptu:

    bash
    nano /usr/local/sbin/zaloha.sh
  2. Wklej zawartość:

    /usr/local/sbin/zaloha.shbash
    #!/bin/bash
    set -euo pipefail
    umask 077
    
    CIL=/var/backups/vps
    DNES=$(date +%F)
    UCHOVAT_DNI=7
    
    mkdir -p "$CIL"
    
    # 1) bazy danych (tylko jeśli zainstalowano MariaDB/MySQL)
    if command -v mariadb-dump >/dev/null 2>&1; then
      mariadb-dump --single-transaction --routines --events --all-databases | gzip > "$CIL/db-$DNES.sql.gz"
    fi
    
    # 2) pliki
    tar -czf "$CIL/soubory-$DNES.tar.gz" --ignore-failed-read /etc /home /root /var/www /opt /srv || [ $? -eq 1 ]
    
    # 3) usuwanie starych kopii
    find "$CIL" -type f -name '*.gz' -mtime +"$UCHOVAT_DNI" -delete
    
    echo "$(date '+%F %T') kopia zapasowa gotowa"
  3. Zapisz (Ctrl+O, Enter), zamknij (Ctrl+X) i nadaj uprawnienie do wykonywania:

    bash
    chmod 700 /usr/local/sbin/zaloha.sh
    • chmod 700 – tylko root może czytać i uruchamiać skrypt.

Co robi skrypt:

LiniaZnaczenie
#!/bin/bashSkrypt działa w interpreterze bash.
set -euo pipefailSkrypt zatrzymuje się przy pierwszym błędzie (-e), przy użyciu nieustawionej zmiennej (-u) i gdy jakiekolwiek polecenie w potoku | się nie powiedzie (pipefail). Dzięki temu nie zostaniesz po cichu z zepsutą kopią.
umask 077Nowe pliki są czytelne tylko dla roota. Kopie zawierają hasła i klucze.
CIL=/var/backups/vpsKatalog kopii na VPS (CIL = „cel”).
DNES=$(date +%F)Dzisiejsza data w formie 2026-10-01 (DNES = „dziś”), używana w nazwach plików (soubory = „pliki”).
UCHOVAT_DNI=7Ile dni przechowywać kopie (UCHOVAT_DNI = „dni do zachowania”). Więcej dni = więcej miejsca na dysku.
command -v mariadb-dumpSprawdza, czy baza jest zainstalowana; jeśli nie, eksport jest pomijany.
mariadb-dump … | gzip > …Eksportuje wszystkie bazy bez blokowania tabel, kompresując w locie. Root loguje się do bazy przez unix socket bez hasła.
tar -czf … /etc /home …Pakuje i kompresuje wymienione katalogi do jednego archiwum.
--ignore-failed-readNie kończy błędem, gdy katalog nie istnieje albo nie da się go odczytać.
|| [ $? -eq 1 ]tar zwraca kod 1, gdy plik zmienił się w trakcie czytania (na przykład log). To w porządku; prawdziwy błąd (kod 2) zatrzymuje skrypt.
find … -mtime +7 -deleteUsuwa archiwa starsze niż 7 dni.
  1. Wypróbuj skrypt ręcznie:

    bash
    /usr/local/sbin/zaloha.sh
    ls -lh /var/backups/vps

    Zobaczysz kopia zapasowa gotowa oraz pliki db-….sql.gz i soubory-….tar.gz. Komunikat tar: Removing leading '/' from member names jest normalny: ścieżki są zapisywane w archiwum bez początkowego ukośnika.

Miejsce na dysku

Kopia leży na tym samym dysku co dane. Zajmuje miejsce, a przy awarii dysku lub przejęciu VPS znika razem z danymi. Pilnuj wolnego miejsca (df -h) i kopiuj kopie poza VPS (zobacz Kopiowanie poza VPS).

Automatyczne uruchamianie przez cron#

  1. Upewnij się, że cron jest zainstalowany (jeśli już jest, nic się nie stanie):

    bash
    apt -y install cron
  2. Otwórz crontab roota:

    bash
    crontab -e

    Przy pierwszym uruchomieniu wybierz edytor nano.

  3. Dodaj tę linię na końcu:

    text
    30 3 * * * /usr/local/sbin/zaloha.sh >> /var/log/zaloha.log 2>&1
  4. Zapisz i zamknij edytor. Zobaczysz crontab: installing new crontab.

Linia crontaba ma pięć pól czasu i polecenie:

PoleDozwolone wartościW przykładzieZnaczenie
minuta0–⁠5930w minucie 30
godzina0–⁠233o 3 w nocy
dzień miesiąca1–⁠31*codziennie
miesiąc1–⁠12*co miesiąc
dzień tygodnia0–⁠7 (0 i 7 = niedziela)*każdego dnia tygodnia
polecenie/usr/local/sbin/zaloha.shco uruchomić (zawsze z pełną ścieżką)
przekierowanie>> /var/log/zaloha.log 2>&1dopisuj wyjście i błędy do logu

Więcej przykładów czasu:

WpisKiedy się uruchamia
0 */6 * * *co 6 godzin (0:00, 6:00, 12:00, 18:00)
15 2 * * 0w każdą niedzielę o 2:15
0 4 1 * *pierwszego dnia miesiąca o 4:00

Czasy odnoszą się do strefy czasowej VPS (timedatectl). Kopie zaplanuj na porę, gdy serwer ma najmniejszy ruch.

Kopiowanie poza VPS#

Przygotowanie dostępu SSH do serwera docelowego#

Wysyłaj kopie na inny serwer (domowy NAS z SSH, inny VPS). W przykładach serwer docelowy ma adres IP 198.51.100.25; użyj adresu własnego serwera.

Na serwerze docelowym (Ubuntu lub Debian, zalogowany jako root) utwórz użytkownika i katalog, do którego może pisać:

bash
adduser zaloha
mkdir -p /srv/zalohy
chown zaloha:zaloha /srv/zalohy
chmod 700 /srv/zalohy
  • adduser zaloha – tworzy użytkownika zaloha. Pyta o hasło (będzie potrzebne w kroku 2 niżej) i o opcjonalne dane, które możesz pominąć klawiszem Enter.
  • mkdir -p /srv/zalohy – katalog kopii.
  • chown zaloha:zaloha – katalog należy do użytkownika zaloha, aby mógł tam pisać. Bez tego zarówno rsync, jak i restic kończą się Permission denied.
  • chmod 700 – nikt inny nie ma dostępu do katalogu.

Logowanie hasłem musi być na serwerze docelowym dozwolone przynajmniej do przesłania klucza (krok 2). Na NAS-ie postępuj według jego instrukcji (użytkownik, folder udostępniony, włączone SSH).

Następnie na archiwizowanym VPS:

  1. Utwórz klucz SSH bez hasła, używany tylko do kopii zapasowych:

    bash
    ssh-keygen -t ed25519 -f /root/.ssh/zaloha -N "" -C "zaloha-vps"
    • -t ed25519 – nowoczesny typ klucza.
    • -f /root/.ssh/zaloha – gdzie zapisać klucz (tworzy zaloha i zaloha.pub).
    • -N "" – bez hasła klucza, aby cron mógł go używać bez Ciebie.
    • -C "zaloha-vps" – etykieta klucza.
  2. Prześlij klucz publiczny na serwer docelowy (wpiszesz hasło użytkownika zaloha na serwerze docelowym):

    bash
    ssh-copy-id -i /root/.ssh/zaloha.pub [email protected]

    Przy pierwszym połączeniu SSH pyta Are you sure you want to continue connecting (yes/no/[fingerprint])?. Wpisz yes: odcisk serwera docelowego zapisze się w /root/.ssh/known_hosts, a cron nie będzie już pytany.

  3. Utwórz skrót połączenia. Otwórz nano /root/.ssh/config i dodaj:

    /root/.ssh/configtext
    Host zalohy
        HostName 198.51.100.25
        User zaloha
        IdentityFile /root/.ssh/zaloha
    • Host zalohy – skrót, którego użyjesz zamiast adresu.
    • HostName – adres IP lub domena serwera docelowego.
    • User – użytkownik na serwerze docelowym.
    • IdentityFile – klucz używany do logowania.
  4. Przetestuj połączenie: ssh zalohy musi zalogować bez hasła. Wyloguj się przez exit.

Szczegóły pracy z kluczami: Klucz SSH.

rsync#

rsync kopiuje tylko zmienione pliki, więc jest szybki nawet przy dużych kopiach. Musi być zainstalowany po obu stronach (apt -y install rsync).

bash
rsync -az /var/backups/vps/ zalohy:/srv/zalohy/vps1/
  • -a – tryb archiwalny: kopiuje rekurencyjnie i zachowuje uprawnienia, czasy i dowiązania.
  • -z – kompresuje dane podczas transferu.
  • /var/backups/vps/ – co kopiować. Ukośnik na końcu oznacza „zawartość katalogu”, nie sam katalog.
  • zalohy:/srv/zalohy/vps1/ – cel: skrót z ~/.ssh/config i katalog na serwerze docelowym.

Dodaj transfer jako ostatnią linię zaloha.sh albo do crontaba godzinę po kopii:

text
30 4 * * * rsync -az /var/backups/vps/ zalohy:/srv/zalohy/vps1/ >> /var/log/zaloha.log 2>&1

Dlaczego bez --delete

Flaga --delete usuwałaby na celu wszystko, czego brakuje na VPS. Gdyby atakujący lub pomyłka usunęli kopie na VPS, następne uruchomienie usunęłoby je także na celu. Stare kopie na serwerze docelowym usuwaj zamiast tego tam, na przykład własnym zadaniem cron z find … -mtime +30 -delete.

Pamiętaj, że atakujący, który przejmie VPS, może też bezpośrednio użyć klucza zaloha i usunąć kopie na celu. Przed tym chroni tylko kopia nieosiągalna z VPS: na przykład serwer docelowy, który sam pobiera kopie (rsync uruchamiany na celu), albo magazyn z historią wersji.

restic (dla zaawansowanych)#

restic przechowuje kopie zaszyfrowane i z deduplikacją: powtarzające się dane są zapisywane tylko raz, więc możesz trzymać dziesiątki dziennych wersji przy małym zużyciu miejsca. Potrafi archiwizować na serwer SFTP, jak i do chmury.

  1. Zainstaluj restic: apt -y install restic.

  2. Utwórz plik z hasłem repozytorium i ogranicz jego uprawnienia:

    bash
    nano /root/.restic-heslo
    chmod 600 /root/.restic-heslo

    Wpisz do pliku długie losowe hasło (generator haseł).

Bez hasła nie przywrócisz

restic szyfruje dane. Jeśli zgubisz hasło, nikt nie odszyfruje kopii, nawet Ty. Trzymaj je także poza VPS (w menedżerze haseł).

  1. Utwórz repozytorium na serwerze docelowym:

    bash
    restic -r sftp:zalohy:/srv/zalohy/restic-vps1 --password-file /root/.restic-heslo init
    • -r sftp:zalohy:/srv/zalohy/restic-vps1 – repozytorium przez SFTP; zalohy to skrót z ~/.ssh/config.
    • --password-file – plik z hasłem, aby restic nie pytał (wymagane dla crona).
    • init – tworzy nowe puste repozytorium. Zobaczysz created restic repository ….
  2. Zarchiwizuj (to polecenie możesz umieścić w skrypcie zamiast archiwum tar; eksport bazy zostaw):

    bash
    restic -r sftp:zalohy:/srv/zalohy/restic-vps1 --password-file /root/.restic-heslo backup /etc /home /root /var/www /opt /srv /var/backups/vps
  3. Usuwaj stare wersje według polityki:

    bash
    restic -r sftp:zalohy:/srv/zalohy/restic-vps1 --password-file /root/.restic-heslo forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
    • forget – usuwa wersje (snapshoty), których polityka nie zachowuje.
    • --keep-daily 7 – zachowuje najnowszą wersję z każdego z ostatnich 7 dni, które mają kopię.
    • --keep-weekly 4, --keep-monthly 6 – dodatkowo jedną wersję na tydzień przez 4 tygodnie i jedną na miesiąc przez 6 miesięcy.
    • --prune – od razu usuwa dane, do których nie odwołuje się już żadna wersja (zwalnia miejsce).

Przydatne polecenia:

Polecenie (z -r … i --password-file …)Co robi
snapshotsWypisuje zapisane wersje z datami.
restore latest --target /tmp/obnovaPrzywraca najnowszą wersję do /tmp/obnova.
restore latest --target /tmp/obnova --include /etc/nginxPrzywraca tylko wybrany katalog.
checkSprawdza integralność repozytorium.

Alternatywą dla restic jest BorgBackup (dokumentacja (otwiera się w nowym oknie)), działający na podobnej zasadzie.

Test przywracania#

Kopia, której nigdy nie próbowano przywrócić, to tylko nadzieja. Testuj ją od czasu do czasu:

  1. Wypisz zawartość archiwum: tar -tzf /var/backups/vps/soubory-2026-10-01.tar.gz | head.

  2. Rozpakuj pojedynczy plik do katalogu tymczasowego:

    bash
    mkdir -p /tmp/obnova
    tar -xzf /var/backups/vps/soubory-2026-10-01.tar.gz -C /tmp/obnova etc/nginx/nginx.conf
    • -x – rozpakuj, -z – format gzip, -f – z pliku.
    • -C /tmp/obnova – dokąd rozpakować (aby nie nadpisać działającego pliku).
    • etc/nginx/nginx.conf – co rozpakować (ścieżka bez początkowego ukośnika).
  3. Sprawdź eksport bazy: zcat /var/backups/vps/db-2026-10-01.sql.gz | head -n 20 musi pokazać początek eksportu SQL.

  4. Pełny test (przywrócenie bazy, uruchomienie aplikacji) zrób na osobnym testowym VPS, nie na produkcyjnym.

Przywrócenie bazy danych nadpisuje bieżące dane

Polecenie gunzip < db-….sql.gz | mariadb przywraca wszystkie bazy z kopii i nadpisuje ich bieżącą zawartość. Na produkcyjnym VPS uruchamiaj je tylko wtedy, gdy naprawdę chcesz wrócić do stanu z kopii. Przywracanie pojedynczej bazy opisuje artykuł MariaDB na VPS.

Weryfikacja#

  • Rano po pierwszej nocy: tail /var/log/zaloha.log zawiera linię kopia zapasowa gotowa.
  • ls -lh /var/backups/vps pokazuje nowe pliki z dzisiejszą datą i sensownym rozmiarem (nie 0 bajtów).
  • Serwer docelowy ma te same pliki (rsync) albo restic snapshots pokazuje dzisiejszą wersję.

Rozwiązywanie problemów#

Cron nie uruchomił skryptu#

Sprawdź, czy cron działa i co zapisał do logu:

bash
systemctl status cron
journalctl -u cron -n 50

Częste przyczyny: w crontabie brakuje pełnej ścieżki do skryptu, skrypt nie jest wykonywalny (chmod 700) albo edytowano crontab innego użytkownika niż root (crontab -l go wypisuje).

mariadb-dump: Got error: 1045: "Access denied for user …"#

Skrypt nie działa jako root albo root bazy używa hasła zamiast unix socketu. Uruchamiaj skrypt z crontaba roota. Jeśli root ma hasło do bazy, zapisz je w /root/.my.cnf, skąd mariadb-dump czyta je automatycznie:

/root/.my.cnfini
[client]
user=root
password=<HASLO_ROOT_BAZY_DANYCH>
  • [client] – grupa opcji dla wszystkich programów klienckich MariaDB (mariadb, mariadb-dump).
  • user, password – dane logowania. Zamiast <HASLO_ROOT_BAZY_DANYCH> wstaw hasło użytkownika bazy root (bez nawiasów ostrych).

Zabezpiecz plik przez chmod 600 /root/.my.cnf, aby nikt inny nie mógł odczytać hasła.

Kopia ma 0 bajtów albo jest podejrzanie mała#

Skrypt zakończył się w połowie. Uruchom go ręcznie i przeczytaj błąd. Dzięki set -euo pipefail błąd eksportu nie przejdzie niezauważony.

Permission denied (publickey) przy rsync lub restic#

Serwer docelowy nie przyjął klucza. Przetestuj ssh zalohy. Jeśli pyta o hasło albo się nie udaje, prześlij klucz ponownie (ssh-copy-id) i sprawdź, czy IdentityFile w /root/.ssh/config wskazuje właściwy plik.

restic: Fatal: wrong password or no key found#

Hasło w /root/.restic-heslo nie pasuje do repozytorium. Sprawdź, czy plik nie zawiera zbędnej spacji ani innego hasła.

restic: Fatal: unable to open config file … Is there a repository at the following location?#

Pod podaną ścieżką nie ma repozytorium (literówka w ścieżce albo nie uruchomiono init).

Dysk się zapełnia#

Kopie nie są usuwane albo są za duże. Sprawdź, czy krok find … -delete się wykonuje, zmniejsz UCHOVAT_DNI i pomiń katalogi z dużymi danymi, które archiwizujesz inaczej.

Podsumowanie

  • Kopiami VPS zarządzamy my; w zakładce Kopie zapasowe przywracasz cały dysk, a nowsze dane przepadają.
  • Pojedyncze pliki i bazy danych przywrócisz tylko z własnych kopii.
  • Bazy archiwizuj eksportem mariadb-dump, pliki archiwum tar albo przez restic.
  • Skrypt uruchamiaj cronem i wysyłaj kopie poza VPS (rsync bez --delete, restic z szyfrowaniem).
  • Regularnie testuj przywracanie.

Wyszukiwanie w poradnikach