cara backup data VPS dengan Restic
Pelajari cara menggunakan Restic untuk cadangan terenkripsi dan terdeduplikasi dari VPS ke S3 atau server lain menggunakan Ubuntu 24.04 secara otomatis.
Mengapa cadangan pada server yang sama bukan merupakan cadangan
Restic adalah alat cadangan sumber terbuka yang gratis. Alat ini mengirimkan snapshot file Anda yang terenkripsi dan terdeduplikasi ke repositori lain: VPS kedua, mesin di rumah, atau penyimpanan objek yang kompatibel dengan S3. Panduan ini menyiapkannya pada Ubuntu 24.04, mulai dari instalasi hingga repositori melalui SFTP, cadangan pertama, timer systemd harian, kebijakan retensi, dan latihan pemulihan untuk membuktikan sistem ini berfungsi. Destinasi harus berupa mesin lain, karena salinan yang berada pada server yang sama akan hilang jika server tersebut rusak.
Direktori backup/ pada mesin yang dicadangkan hanya melindungi Anda dari satu hal: menghapus file secara tidak sengaja. Direktori tersebut tidak akan selamat jika disk rusak, karena direktori tersebut berada di dalam disk tersebut. Direktori tersebut tidak akan selamat dari penyerang dengan akses root, karena mereka akan menghapus salinan terlebih dahulu. Direktori tersebut tidak akan selamat dari kesalahan akun yang menghapus VPS itu sendiri. Pusat data yang paling tidak efisien di dunia bercanda tentang file tar bernama backup_final_v2_REAL yang berada pada array yang sama dengan data, dan lelucon tersebut relevan karena banyak dari kita pernah melakukan hal tersebut. Menyimpan cadangan di luar mesin adalah aturan utama, dan restic adalah cara termudah untuk mematuhinya.
Restic dalam empat konsep
Repository. Tempat restic menulis data. Ini adalah direktori dengan format khusus restic yang berisi blob terenkripsi, dan hanya restic yang dapat membacanya. Jangan mengedit direktori ini secara manual; gunakan perintah restic dan alamat -r untuk berinteraksi dengannya.
Snapshot. Gambaran file pada satu titik waktu tertentu. Setiap proses backup membuat satu snapshot. Setiap snapshot dapat dipulihkan secara mandiri, dan setiap snapshot berfungsi seperti salinan lengkap data Anda pada saat itu.
Deduplication. Restic membagi file menjadi potongan (chunk) berbasis konten dan hanya mengunggah potongan yang belum ada di repository. Backup pertama akan mengunggah seluruh data; setiap proses setelah itu hanya mengunggah data yang berubah. Snapshot harian sebesar 20 GB dengan perubahan 50 MB hanya membutuhkan ruang sekitar 50 MB, sehingga menyimpan puluhan snapshot sangat efisien.
Encryption by default. Repository restic selalu terenkripsi (AES-256), dan setiap perintah memerlukan kata sandi repository. Host backup atau penyedia penyimpanan hanya akan melihat blob terenkripsi. Konsekuensi utamanya: jika Anda kehilangan kata sandi, data akan hilang secara permanen sesuai desain sistem. Simpan salinan kata sandi di lokasi yang berbeda dari server ini. Hal ini sangat penting sehingga akan dibahas dua kali lagi di bawah ini.
Install restic on Ubuntu 24.04
sudo apt update && sudo apt install -y restic
restic versionPada Ubuntu 24.04, proses ini menginstal restic 0.16.4, sedangkan rilis upstream terbaru adalah 0.19.1. Perbedaan ini terjadi karena rilis LTS (long term support) membekukan versi paketnya, namun hal ini tidak menjadi masalah: versi 0.16.4 dapat menjalankan semua instruksi dalam panduan ini. Jika Anda menginginkan rilis terbaru untuk peningkatan kecepatan, unduh build single-binary resmi dari halaman GitHub releases proyek restic, ekstrak dengan bunzip2, dan instal ke /usr/local/bin/restic; instalasi restic tidak memerlukan langkah tambahan lainnya.
Buat repositori pada server lain melalui SFTP
Anda memerlukan mesin tujuan: VPS kecil kedua adalah solusi umum, dan mesin apa pun dengan server SSH serta ruang disk tersedia dapat digunakan. Restic menggunakan protokol SFTP (transfer file melalui SSH), sehingga host cadangan tidak perlu menginstal aplikasi apa pun. Dalam panduan ini, host cadangan adalah 10.0.0.12 dengan pengguna bernama restic. Jangan beri nama pengguna tersebut backup: Ubuntu dan Debian menyertakan akun sistem cadangan bernama backup (uid 34, tanpa login shell) pada setiap instalasi, sehingga adduser backup akan gagal dan ssh backup@... akan masuk ke nologin.
Tugas rutin malam hari akan berjalan sebagai root pada server yang dicadangkan, sehingga root memerlukan login kunci ke host cadangan. Buat kunci khusus tanpa passphrase, karena tidak ada manusia yang mengetikkannya pada jam 3 pagi, lalu salin kunci tersebut:
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 worksJika Anda belum terbiasa dengan kunci SSH, dasar-dasar manajemen kunci SSH menjelaskan model, izin, dan cara mencabut kunci di kemudian hari.
Selanjutnya, kata sandi repositori. Buat kata sandi yang kuat ke dalam file yang hanya bisa diakses root:
openssl rand -base64 32 | sudo tee /root/.restic-password
sudo chmod 600 /root/.restic-passwordSekarang salin kata sandi tersebut ke pengelola kata sandi Anda sebelum melanjutkan. Jika VPS ini rusak, repositori beserta kata sandi ini akan mengembalikan semuanya; repositori tanpa kata sandi tidak dapat mengembalikan apa pun.
Inisialisasi repositori:
sudo restic -r sftp:restic@10.0.0.12:/srv/restic/web1 --password-file /root/.restic-password initcreated restic repository 9f3c2a1b0d at sftp:restic@10.0.0.12:/srv/restic/web1Destinasi alternatif adalah penyimpanan objek yang kompatibel dengan S3, yang merupakan pilihan tepat jika Anda tidak ingin menjalankan mesin kedua. Setiap bucket yang kompatibel dengan S3 bekerja dengan cara yang sama; hanya alamat dan dua variabel kredensial yang berubah:
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 initSemua langkah setelah init identik untuk kedua destinasi. Sisa panduan ini menggunakan alamat SFTP; silakan ganti dengan alamat Anda sendiri.
Cadangan pertama, dengan pengecualian
Cadangkan data yang tidak dapat diinstal ulang, bukan seluruh sistem berkas. Sistem operasi dapat dipulihkan melalui instalasi ulang; konfigurasi dan data Anda tidak. Untuk VPS pada umumnya, ini berarti /etc, /home, dan lokasi aplikasi menyimpan status, seperti /srv atau /var/www. Kecualikan cache, karena ukurannya besar, berubah setiap hari, dan dapat dibangun ulang secara otomatis:
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 savedProses pertama akan mengunggah semuanya, sehingga memakan waktu lama. Jalankan perintah yang sama lagi dan proses akan selesai dalam hitungan detik, melaporkan beberapa berkas yang berubah dan beberapa MiB yang ditambahkan, karena deduplikasi hanya mengunggah chunk baru. Lihat daftar cadangan Anda:
sudo restic -r sftp:restic@10.0.0.12:/srv/restic/web1 --password-file /root/.restic-password snapshotsSetiap snapshot menampilkan ID, waktu, dan jalur yang dikandungnya. ID tersebut adalah yang digunakan saat melakukan restorasi.
Eksekusi nightly dengan systemd timer
Mengetik alamat repositori pada setiap perintah sangat tidak efisien, dan cadangan yang dijalankan secara manual biasanya akan terhenti dalam waktu satu bulan. Kedua masalah ini dapat diatasi dengan satu skrip dan satu timer. Skrip tersebut mengatur dua variabel lingkungan yang dibaca oleh restic, yaitu RESTIC_REPOSITORY dan RESTIC_PASSWORD_FILE, sehingga setiap perintah di dalamnya menjadi lebih singkat:
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 checksudo chmod 700 /usr/local/bin/restic-backup.shBaris forget dan check dijelaskan pada dua bagian berikutnya. Berikut adalah jadwalnya: sebuah layanan oneshot yang menjalankan skrip, dan sebuah timer yang memicu layanan tersebut pada pukul 03:00 setiap malam. Penggunaan timer lebih baik daripada cron dalam kasus ini karena log eksekusi tersimpan di journal, dan Persistent=true akan menjalankan cadangan yang terlewat segera setelah server menyala kembali setelah downtime.
# /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.targetAktifkan timer, lalu jalankan layanan satu kali secara manual untuk memverifikasi fungsinya:
sudo systemctl daemon-reload
sudo systemctl enable --now restic-backup.timer
sudo systemctl start restic-backup.service
sudo journalctl -u restic-backup.service -fsystemctl list-timers menunjukkan kapan eksekusi berikutnya akan berjalan. Anda juga dapat membuat pasangan file unit secara otomatis daripada mengetiknya secara manual:
Pola lengkap di balik kedua file ini, termasuk sintaks kalender dan direktif pengamanan (hardening) yang dapat digunakan layanan, tersedia di menjalankan program sebagai layanan systemd pada VPS.
Cadangan hanyalah rumor sampai Anda melakukan restorasi
Anggap kalimat tersebut sebagai perintah. Pekerjaan backup yang berjalan sukses setiap malam hanya membuktikan bahwa proses tersebut telah berjalan; hal itu tidak membuktikan data Anda dapat dikembalikan. Dua pemeriksaan diperlukan untuk menutup celah tersebut.
Pertama, restic check, yang sudah dijalankan skrip setiap malam. Proses ini memverifikasi struktur repositori dan indeks, sehingga korupsi data yang tidak terdeteksi pada host backup akan ditemukan pada malam berikutnya, bukan pada hari restorasi. Sekali sebulan, jalankan versi yang lebih mendalam, yang mengunduh dan memverifikasi data aktual secara kriptografis sebesar sepersepuluh bagian secara acak:
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%Karena subset yang diambil bersifat acak setiap saat, proses bulanan ini akan menyisir seluruh repositori tanpa perlu melakukan pengunduhan penuh.
Kedua, latihan restorasi. Masih dalam root shell dari langkah sebelumnya, restorasi satu direktori asli dari snapshot terbaru ke lokasi sementara, lalu bandingkan dengan file yang sedang berjalan:
restic restore latest --target /srv/restore-drill --include /etc/ssh
diff -r /etc/ssh /srv/restore-drill/etc/sshJika diff tidak mencetak apa pun, berarti setiap byte kembali secara identik, yang merupakan satu-satunya bukti yang valid. Hapus /srv/restore-drill setelahnya. Lakukan latihan ini setiap bulan, dan satu atau dua kali setahun lakukan versi lengkap: restorasi seluruh snapshot terbaru ke VPS sementara dan pastikan aplikasi Anda benar-benar dapat berjalan dari sana. Saat Anda membutuhkan ini bekerja di bawah tekanan, Anda ingin proses tersebut menjadi rutinitas yang sudah pernah Anda lakukan.
Retention: forget plus prune
Tanpa kebijakan, snapshot akan terus menumpuk dan ukuran repositori akan terus bertambah. Baris forget pada skrip menerapkan kebijakan setiap malam: --keep-daily 7 menyimpan satu snapshot per hari selama tujuh hari terakhir, --keep-weekly 4 satu per minggu selama empat minggu, dan --keep-monthly 6 satu per bulan selama enam bulan. Semua data yang tidak dilindungi oleh aturan akan dihapus.
forget secara mandiri hanya menghapus catatan snapshot; potongan data (data chunks) tetap ada di repositori sampai ada proses yang menghapusnya. Itulah fungsi --prune: ia mencari potongan data yang tidak lagi memiliki referensi snapshot dan menghapusnya, sehingga ruang disk benar-benar kembali. Prune melakukan pembersihan repositori yang sebenarnya, sehingga pada repositori besar beberapa orang menjalankan forget setiap malam dan --prune setiap minggu; untuk ukuran VPS tipikal, menjalankan setiap malam sudah cukup.
Databases: lakukan dump terlebih dahulu, baru cadangkan dump tersebut
Restic menyalin file saat membacanya, sedangkan database menulis ke file secara terus-menerus. File database aktif yang diambil saat proses penulisan berlangsung akan pulih sebagai database yang korup, karena salinan tersebut mencampur halaman dari sebelum dan sesudah penulisan. Solusi standarnya adalah: biarkan mesin database menghasilkan ekspor yang konsisten ke sebuah file, lalu biarkan restic mencadangkan file tersebut.
Untuk PostgreSQL, tambahkan baris dump di bagian atas restic-backup.sh, sebelum perintah restic backup, dan sertakan direktori dump dalam jalur cadangan:
mkdir -p /var/backups/db
sudo -u postgres pg_dump myapp | gzip > /var/backups/db/myapp.sql.gzmysqldump menjalankan peran yang sama untuk MariaDB dan MySQL. Untuk contoh penerapan pola ini secara utuh, bagian cadangan Nextcloud mengaktifkan mode pemeliharaan, melakukan dump Postgres, dan menyalin file sebagai satu set yang konsisten, yaitu set yang harus dibawa restic keluar dari sistem setiap malam. SQLite menggunakan konsep yang sama dengan cara yang lebih sederhana: panduan Vaultwarden menghentikan kontainer selama beberapa detik untuk mengambil salinan dingin dari db.sqlite3, dan arsip itulah yang dikirim restic keluar dari server.
FAQ
Are restic backups encrypted?
Yes, always. Every restic repository is encrypted with AES-256, there is no unencrypted mode, and every command requires the repository password. The machine or provider storing the repository only ever holds encrypted blobs, so a compromised backup host does not expose your files. The trade is absolute: without the password the data cannot be recovered by anyone, so store a copy of it away from the server.
Does restic do incremental backups?
Every restic snapshot behaves like a full backup, while costing incremental storage. Restic splits files into chunks and uploads only chunks the repository has not already stored, so a nightly run transfers roughly what changed that day. Unlike traditional incremental schemes, there is no chain to replay: any snapshot restores directly and deleting an old snapshot never breaks a newer one.
How do I restore files from a restic backup?
Run restic snapshots to find the snapshot ID, then restic restore <id> --target /some/empty/dir to restore it, adding --include /path to restore only part of it. latest works in place of an ID. Restic recreates the original directory structure under the target, so restoring /etc/ssh lands in /some/empty/dir/etc/ssh. Practice this before you need it, because an untested backup is a rumor.
How often should I run restic backup?
Nightly is the sensible floor for a server, and deduplication makes it cheap: each run uploads only the chunks that changed since the last one. Data that changes fast, or that would hurt to lose even a day of, can run every few hours with the same timer pattern. Frequency is the easy half; also run restic check regularly and a restore drill monthly, because schedule without verification is false comfort.
What happens if I lose my restic repository password?
The backups are unrecoverable. Restic's encryption has no back door and no reset, so the password is as important as the backups themselves. Keep a copy in your password manager and anywhere else durable that is not the backed-up server. While you still have access, restic key add can register a second password for the same repository, which gives you a spare.