SSD Nodes Learn Hosting plans →
Przewodniki Matt ConnorAutor: Matt Connor · Zaktualizowano 2026-08-07

Jak wykonać kopię zapasową VPS za pomocą Restic

Konfiguracja Restic na Ubuntu 24.04 pozwala na bezpieczne przesyłanie zaszyfrowanych danych do zdalnego repozytorium. Artykuł wyjaśnia automatyzację przez systemd i retencję.

Dlaczego kopia zapasowa na tym samym serwerze nie jest kopią zapasową

Restic to darmowe, otwartoźródłowe narzędzie do tworzenia kopii zapasowych, które wysyła zaszyfrowane i zdeduplikowane migawki plików do zewnętrznego repozytorium: na drugi serwer VPS, maszynę domową lub pamięć obiektową zgodną z S3. Niniejszy przewodnik opisuje konfigurację na systemie Ubuntu 24.04, począwszy od instalacji, przez repozytorium SFTP, wykonanie pierwszej kopii, aż po harmonogram systemd, politykę retencji oraz procedurę przywracania danych, która potwierdza poprawność całego procesu. Miejsce docelowe musi znajdować się na innej maszynie, ponieważ kopia przechowywana na tym samym serwerze ginie wraz z nim.

Katalog backup/ na serwerze, z którego tworzona jest kopia, chroni wyłącznie przed przypadkowym usunięciem pliku. Nie przetrwa on awarii dysku, ponieważ znajduje się na tym samym nośniku. Nie oprze się atakującemu z uprawnieniami root, ponieważ usunie on kopie w pierwszej kolejności. Nie zabezpieczy również przed błędem na koncie, który skutkuje usunięciem samego serwera VPS. Najmniej wydajne centrum danych na świecie żartuje z archiwum tar o nazwie backup_final_v2_REAL, które znajduje się na tej samej macierzy co dane – ten żart jest trafny, ponieważ wielu z nas dokładnie tak postępowało. Zasada brzmi: dane muszą znajdować się poza serwerem, a restic jest najmniej uciążliwym sposobem na jej przestrzeganie.

Restic w czterech punktach

Repozytorium. Miejsce, do którego restic zapisuje dane. Jest to katalog w formacie restic, wypełniony zaszyfrowanymi obiektami (blobs), które może odczytać wyłącznie restic. Nie należy edytować go ręcznie; komunikacja odbywa się za pomocą poleceń restic oraz adresu -r.

Migawka (Snapshot). Obraz plików w określonym momencie. Każde uruchomienie kopii zapasowej tworzy migawkę, którą można przywrócić niezależnie. Każda migawka zachowuje się jak kompletna kopia danych z danego momentu.

Deduplikacja. Restic dzieli pliki na fragmenty zależne od ich zawartości i przesyła tylko te, których w repozytorium jeszcze nie ma. Pierwsza kopia zapasowa przesyła wszystko; każde kolejne uruchomienie przesyła tylko to, co uległo zmianie. Nocna migawka o rozmiarze 20 GB, w której zmieniło się 50 MB, zajmuje około 50 MB, dlatego przechowywanie dziesiątek migawek jest efektywne kosztowo.

Szyfrowanie domyślne. Repozytorium restic jest zawsze szyfrowane (AES-256), a każde polecenie wymaga podania hasła do repozytorium. Host wykonujący kopię zapasową lub dostawca pamięci masowej widzi wyłącznie zaszyfrowane obiekty. Konsekwencja jest surowa: utrata hasła oznacza bezpowrotną utratę danych, co jest zamierzonym działaniem. Należy przechowywać kopię hasła w miejscu innym niż dany serwer. Kwestia ta jest na tyle istotna, że pojawia się poniżej jeszcze dwukrotnie.

Instalacja restic na Ubuntu 24.04

sudo apt update && sudo apt install -y restic
restic version

W systemie Ubuntu 24.04 powyższa procedura instaluje restic w wersji 0.16.4, podczas gdy aktualne wydanie upstream to 0.19.1. Rozbieżność wynika z faktu, że wydania LTS (long term support) zamrażają wersje pakietów, co w tym przypadku nie ma znaczenia: wersja 0.16.4 realizuje wszystkie zadania opisane w tym przewodniku. Jeśli wymagane jest najnowsze wydanie ze względu na poprawę wydajności, należy pobrać oficjalny plik binarny ze strony wydań projektu restic w serwisie GitHub, rozpakować go za pomocą bunzip2 i zainstalować w /usr/local/bin/restic; instalacja restic nie wymaga żadnych dodatkowych kroków.

Utworzenie repozytorium na innym serwerze przez SFTP

Wymagana jest maszyna docelowa: zazwyczaj wystarcza drugi, niewielki VPS lub dowolny serwer z uruchomionym SSH i wolnym miejscem na dysku. Restic obsługuje protokół SFTP (przesyłanie plików przez SSH), więc na hoście docelowym nie trzeba instalować żadnego dodatkowego oprogramowania. W tym przewodniku hostem kopii zapasowej jest 10.0.0.12 z użytkownikiem restic. Nie należy nazywać tego użytkownika backup: systemy Ubuntu i Debian domyślnie tworzą zarezerwowane konto systemowe o nazwie backup (uid 34, bez powłoki logowania), dlatego adduser backup zakończy się niepowodzeniem, a ssh backup@... trafi do nologin.

Zadanie wykonywane w nocy będzie uruchamiane jako root na serwerze źródłowym, dlatego użytkownik root musi mieć możliwość logowania się do hosta docelowego przy użyciu klucza. Należy utworzyć dedykowany klucz bez hasła, ponieważ o godzinie 3:00 rano nikt nie będzie obecny, aby je wpisać, a następnie skopiować klucz:

sudo ssh-keygen -t ed25519 -f /root/.ssh/id_ed25519 -N "" -C "web1-restic"
sudo ssh-copy-id -i /root/.ssh/id_ed25519.pub restic@10.0.0.12
sudo ssh restic@10.0.0.12 true && echo key login works

Jeśli obsługa kluczy jest nowym zagadnieniem, podstawy zarządzania kluczami SSH wyjaśniają ten model, uprawnienia oraz sposób późniejszego unieważnienia klucza.

Następnie należy przygotować hasło do repozytorium. Wygeneruj silne hasło i zapisz je w pliku dostępnym tylko dla użytkownika root:

openssl rand -base64 32 | sudo tee /root/.restic-password
sudo chmod 600 /root/.restic-password

Przed kontynuowaniem skopiuj to hasło do menedżera haseł. W przypadku awarii serwera VPS, repozytorium wraz z tym hasłem pozwoli na pełne odzyskanie danych; samo repozytorium bez hasła jest bezużyteczne.

Zainicjuj repozytorium:

sudo restic -r sftp:restic@10.0.0.12:/srv/restic/web1 --password-file /root/.restic-password init
created restic repository 9f3c2a1b0d at sftp:restic@10.0.0.12:/srv/restic/web1

Alternatywnym miejscem docelowym jest pamięć obiektowa zgodna z S3, co stanowi właściwy wybór, gdy nie chcesz utrzymywać drugiej maszyny. Każdy bucket zgodny z S3 działa w ten sam sposób; zmienia się jedynie adres oraz dwie zmienne z danymi uwierzytelniającymi:

export AWS_ACCESS_KEY_ID=your-key-id
export AWS_SECRET_ACCESS_KEY=your-secret-key
sudo -E restic -r s3:https://s3.example.com/web1-backups --password-file /root/.restic-password init

Wszystkie kroki po init są identyczne dla obu typów lokalizacji. Reszta tego przewodnika zakłada użycie adresu SFTP; należy podstawić własne dane.

Pierwsza kopia zapasowa z wykluczeniami

Należy tworzyć kopie zapasowe danych, których nie można zainstalować ponownie, a nie całego systemu plików. System operacyjny można odtworzyć poprzez ponowną instalację; konfiguracja i dane użytkownika nie. W przypadku typowego VPS oznacza to /etc, /home oraz lokalizacje, w których aplikacje przechowują swój stan, takie jak /srv lub /var/www. Należy wykluczyć pamięci podręczne (cache), ponieważ zajmują dużo miejsca, ulegają ciągłym zmianom i są odtwarzane automatycznie:

sudo restic -r sftp:restic@10.0.0.12:/srv/restic/web1 --password-file /root/.restic-password backup /etc /home /srv --exclude '/home/*/.cache'
Files:        4181 new,     0 changed,     0 unmodified
Added to the repository: 731.204 MiB (312.418 MiB stored)
snapshot 5b8a3f2c saved

Pierwsze uruchomienie przesyła wszystkie dane, więc trwa dłużej. Ponowne wykonanie tego samego polecenia kończy się w kilka sekund, raportując zmianę kilku plików i dodanie kilku MiB, ponieważ deduplikacja przesyła tylko nowe fragmenty danych. Wyświetlanie listy posiadanych kopii:

sudo restic -r sftp:restic@10.0.0.12:/srv/restic/web1 --password-file /root/.restic-password snapshots

Każdy snapshot posiada identyfikator, czas utworzenia oraz listę zawartych w nim ścieżek. Identyfikatory te służą do przywracania danych.

Wykonywanie zadań w nocy za pomocą systemd timer

Wpisywanie adresu repozytorium przy każdym poleceniu staje się uciążliwe, a kopia zapasowa wykonywana ręcznie przestaje być tworzona w ciągu miesiąca. Oba problemy rozwiązuje jeden skrypt i jeden timer. Skrypt ustawia dwie zmienne środowiskowe odczytywane przez restic, RESTIC_REPOSITORY oraz RESTIC_PASSWORD_FILE, dzięki czemu każde polecenie wewnątrz pozostaje krótkie:

sudo nano /usr/local/bin/restic-backup.sh
#!/usr/bin/env bash
set -euo pipefail
export RESTIC_REPOSITORY='sftp:restic@10.0.0.12:/srv/restic/web1'
export RESTIC_PASSWORD_FILE=/root/.restic-password

restic backup /etc /home /srv --exclude '/home/*/.cache'
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
restic check
sudo chmod 700 /usr/local/bin/restic-backup.sh

Linie forget oraz check zostały wyjaśnione w dwóch kolejnych sekcjach. Teraz harmonogram: usługa oneshot, która uruchamia skrypt, oraz timer, który wyzwala go codziennie o godzinie 03:00. Timer jest lepszy od wpisu w cron, ponieważ loguje przebieg do journal, a Persistent=true uruchamia pominiętą kopię zapasową natychmiast po przywróceniu działania serwera po przestoju.

# /etc/systemd/system/restic-backup.service
[Unit]
Description=Nightly restic backup
Wants=network-online.target
After=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/restic-backup.sh
# /etc/systemd/system/restic-backup.timer
[Unit]
Description=Run the nightly restic backup

[Timer]
OnCalendar=*-*-* 03:00:00
RandomizedDelaySec=15m
Persistent=true

[Install]
WantedBy=timers.target

Włącz timer, a następnie uruchom usługę ręcznie i obserwuj jej działanie:

sudo systemctl daemon-reload
sudo systemctl enable --now restic-backup.timer
sudo systemctl start restic-backup.service
sudo journalctl -u restic-backup.service -f

systemctl list-timers pokazuje, kiedy nastąpi kolejne uruchomienie. Można również wygenerować parę plików jednostek zamiast wpisywać je ręcznie:

ToolGenerate the backup service and timer

Pełny schemat dotyczący tych dwóch plików, w tym składnia kalendarza oraz dyrektywy utwardzające, które może zawierać usługa, znajduje się w uruchamianie programu jako usługa systemd na VPS.

Backup to tylko plotka, dopóki nie zostanie przywrócony

Traktuj to zdanie jak przykazanie. Zadanie kopii zapasowej, które każdej nocy kończy się powodzeniem, dowodzi jedynie, że proces został uruchomiony; nie stanowi dowodu na to, że dane można odzyskać. Dwie kontrole pozwalają wyeliminować to ryzyko.

Po pierwsze, restic check, który skrypt uruchamia już każdej nocy. Weryfikuje on strukturę repozytorium oraz indeks, dzięki czemu ciche uszkodzenia danych na hoście kopii zapasowych zostaną wykryte następnej nocy, a nie w dniu próby przywracania. Raz w miesiącu należy uruchomić wersję rozszerzoną, która pobiera i kryptograficznie weryfikuje losową dziesiątą część rzeczywistych danych:

sudo -i
export RESTIC_REPOSITORY='sftp:restic@10.0.0.12:/srv/restic/web1'
export RESTIC_PASSWORD_FILE=/root/.restic-password
restic check --read-data-subset=10%

Ponieważ podzbiór danych jest za każdym razem losowy, comiesięczne uruchomienia pozwalają na sprawdzenie całego repozytorium bez konieczności każdorazowego pobierania wszystkich danych.

Po drugie, ćwiczenie przywracania. Pozostając w powłoce root z poprzednich kroków, przywróć jeden rzeczywisty katalog z najnowszego snapshot do tymczasowej lokalizacji i porównaj go z aktywnymi plikami:

restic restore latest --target /srv/restore-drill --include /etc/ssh
diff -r /etc/ssh /srv/restore-drill/etc/ssh

diff brak danych wyjściowych oznacza, że każdy bajt został przywrócony identycznie, co jest jedynym wiarygodnym dowodem. Po zakończeniu usuń /srv/restore-drill. Wykonuj to ćwiczenie co miesiąc, a raz lub dwa razy w roku przeprowadź pełną wersję: przywróć cały najnowszy snapshot na tymczasowy VPS i sprawdź, czy aplikacja faktycznie się z niego uruchamia. W dniu, w którym będziesz musiał to zrobić pod presją czasu, chcesz, aby była to procedura, którą już znasz z praktyki.

Retencja: forget oraz prune

Bez zdefiniowanej polityki migawki gromadzą się w nieskończoność, a rozmiar repozytorium stale rośnie. Linia forget w skrypcie stosuje politykę każdej nocy: --keep-daily 7 zachowuje jedną migawkę dziennie z ostatnich siedmiu dni, --keep-weekly 4 jedną tygodniowo z czterech tygodni, a --keep-monthly 6 jedną miesięcznie z sześciu miesięcy. Wszystkie migawki nieobjęte regułami są usuwane z indeksu.

Samo forget usuwa jedynie wpisy o migawkach; fragmenty danych pozostają w repozytorium, dopóki nie zostaną usunięte. Do tego służy --prune: wyszukuje fragmenty, do których nie odwołuje się żadna migawka, i usuwa je, co pozwala na odzyskanie miejsca na dysku. Operacja prune obciąża repozytorium, dlatego w przypadku dużych zbiorów danych niektórzy uruchamiają forget co noc, a --prune raz w tygodniu; przy typowych rozmiarach VPS codzienne uruchamianie jest dopuszczalne.

Bazy danych: najpierw zrzut, potem kopia zapasowa

Restic kopiuje pliki w trakcie ich odczytu, podczas gdy baza danych zapisuje dane w sposób ciągły. Plik aktywnej bazy danych przechwycony w trakcie zapisu po przywróceniu będzie uszkodzony, ponieważ kopia zawiera wymieszane strony sprzed i po operacji zapisu. Rozwiązanie jest standardowe: należy wymusić na silniku bazy danych wygenerowanie spójnego eksportu do pliku, a następnie pozwolić narzędziu restic na wykonanie kopii zapasowej tego pliku.

W przypadku PostgreSQL należy dodać linię ze zrzutem na początku pliku restic-backup.sh, przed poleceniem restic backup, oraz uwzględnić katalog ze zrzutem w ścieżkach kopii zapasowej:

mkdir -p /var/backups/db
sudo -u postgres pg_dump myapp | gzip > /var/backups/db/myapp.sql.gz

mysqldump pełni tę samą rolę w przypadku MariaDB oraz MySQL. Jako przykład praktycznego zastosowania całego schematu, sekcja dotycząca kopii zapasowej Nextcloud włącza tryb konserwacji, wykonuje zrzut Postgres i kopiuje pliki jako jeden spójny zestaw – dokładnie taki, jaki restic powinien każdej nocy przesyłać poza serwer. W przypadku SQLite zasada jest podobna, choć stosuje się prostsze środki: przewodnik po Vaultwarden zatrzymuje kontener na kilka sekund, aby wykonać kopię „na zimno” pliku db.sqlite3, a to właśnie to archiwum jest przesyłane przez restic poza serwer.

FAQ

Czy kopie zapasowe restic są szyfrowane?

Tak, zawsze. Każde repozytorium restic jest szyfrowane za pomocą AES-256. Nie istnieje tryb bez szyfrowania, a każde polecenie wymaga podania hasła do repozytorium. Maszyna lub dostawca przechowujący repozytorium otrzymuje wyłącznie zaszyfrowane obiekty (bloby), więc naruszenie bezpieczeństwa hosta kopii zapasowych nie powoduje ujawnienia plików. Ceną jest bezwzględność: bez hasła danych nie odzyska nikt, dlatego należy przechowywać kopię hasła poza serwerem.

Czy restic wykonuje kopie przyrostowe?

Każdy snapshot restic zachowuje się jak pełna kopia zapasowa, zajmując przy tym miejsce odpowiadające kopii przyrostowej. Restic dzieli pliki na fragmenty (chunks) i przesyła tylko te, których w repozytorium jeszcze nie ma. Dzięki temu nocne uruchomienie przesyła w przybliżeniu tylko to, co zmieniło się danego dnia. W przeciwieństwie do tradycyjnych schematów przyrostowych, nie ma tu łańcucha zależności do odtwarzania: każdy snapshot można przywrócić bezpośrednio, a usunięcie starego snapshota nigdy nie uszkodzi nowszego.

Jak przywrócić pliki z kopii zapasowej restic?

Uruchom restic snapshots, aby znaleźć ID snapshota, a następnie restic restore <id> --target /some/empty/dir, aby go przywrócić. Użyj --include /path, aby przywrócić tylko jego część. latest działa zamiennie z ID. Restic odtwarza oryginalną strukturę katalogów w miejscu docelowym, więc przywrócenie /etc/ssh trafi do /some/empty/dir/etc/ssh. Przetestuj ten proces przed wystąpieniem awarii, ponieważ niesprawdzona kopia zapasowa to tylko przypuszczenie.

Jak często należy uruchamiać kopię zapasową restic?

Dla serwera rozsądnym minimum jest częstotliwość dobowa, a deduplikacja sprawia, że jest to tanie rozwiązanie: każde uruchomienie przesyła tylko fragmenty, które zmieniły się od ostatniego razu. Dane, które zmieniają się szybko lub których utrata nawet za jeden dzień byłaby dotkliwa, można archiwizować co kilka godzin przy użyciu tego samego harmonogramu. Częstotliwość to łatwiejsza połowa zadania; należy również regularnie uruchamiać restic check oraz raz w miesiącu przeprowadzać próbne przywracanie danych, ponieważ harmonogram bez weryfikacji daje jedynie złudne poczucie bezpieczeństwa.

Co się stanie, jeśli zgubię hasło do repozytorium restic?

Kopie zapasowe stają się niemożliwe do odzyskania. Szyfrowanie restic nie posiada tylnych furtek ani mechanizmu resetowania, więc hasło jest równie ważne, co same kopie zapasowe. Przechowuj kopię hasła w menedżerze haseł oraz w innym trwałym miejscu, które nie jest serwerem objętym kopią zapasową. Dopóki masz dostęp do repozytorium, polecenie restic key add pozwala zarejestrować drugie hasło dla tego samego repozytorium, co zapewnia zapasowy sposób dostępu.