- restic = backup tool open source, deduplication + encryption + snapshot atomic, single binary Go.
- Backblaze B2 = object storage rẻ nhất (~6 USD/TB/tháng), tương thích S3 API, free 10GB.
- Backup hằng ngày tự động qua systemd timer, dump DB + sync folder + giữ 7/4/12 snapshot rotation.
- Encryption client-side AES-256, Backblaze không đọc được data của bạn.
- Cost < 1 USD/tháng cho VPS 100 GB nén+dedupe, test restore mỗi quý đảm bảo recovery thực sự.
Founder solo có VPS chạy app sản xuất: code, database, file upload user, log nginx. 1 ngày VPS bị xóa nhầm (provider lỗi billing, kẻ tấn công rm -rf, ổ SSD chết). Không backup = bay luôn 6 tháng build. Snapshot của VPS provider tốt nhưng không phải mọi lúc đều tin được, và họ chỉ giữ 7 ngày. Mình cần backup riêng, ra ngoài provider, mã hóa, rẻ. restic + Backblaze B2 là combo tối ưu nhất hiện tại.
Bài này hướng dẫn setup từ đầu: cài restic, tạo bucket B2, init repo, viết script backup hằng ngày qua systemd timer, áp dụng retention policy, test restore. Tham khảo workflow của nhiều solo dev đang dùng combo này nhiều năm với cost dưới 1 USD/tháng.
Vì sao restic + B2 thay vì borgbackup, duplicity, rsnapshot?
- restic dedupe block-level: file 10 GB chỉ thay 1 MB, upload đúng 1 MB delta.
- Single binary Go, no dependency: copy file binary là chạy, không phải pip install.
- Encryption AES-256 GCM bắt buộc, key client giữ, server không đọc được.
- Hỗ trợ nhiều backend: S3, B2, Azure, GCS, SFTP, local disk - chuyển backend dễ.
- Snapshot atomic + immutable: 1 lần backup = 1 snapshot riêng, không corrupt được.
- Cộng đồng lớn, doc tốt, dev active từ 2015.
B2 vs S3 vs R2: B2 download miễn phí 3x storage volume mỗi tháng (rất hào phóng cho restore use case), giá storage thấp hơn S3 50%, có giao diện đơn giản. R2 free egress hoàn toàn nhưng storage nhỉnh hơn B2. Đa số chọn B2 cho backup vì cost predictable.
Cài restic
# AlmaLinux 9
sudo dnf install -y restic
# Ubuntu / Debian
sudo apt update && sudo apt install -y restic
# Hoặc download binary mới nhất từ Github
RESTIC_VER=0.17.3
wget https://github.com/restic/restic/releases/download/v${RESTIC_VER}/restic_${RESTIC_VER}_linux_amd64.bz2
bunzip2 restic_${RESTIC_VER}_linux_amd64.bz2
sudo install -m 755 restic_${RESTIC_VER}_linux_amd64 /usr/local/bin/restic
# Verify
restic version
Tạo bucket Backblaze B2
- Đăng ký tài khoản Backblaze, vào B2 Cloud Storage.
- Create Bucket: tên "my-vps-backup", Files in Bucket private, lifecycle "Keep all versions of files".
- App Keys -> Add a New Application Key: giới hạn chỉ bucket "my-vps-backup", read+write+delete (cần delete cho prune).
- Lưu keyID và applicationKey - chỉ hiện 1 lần, mất thì phải tạo key mới.
Init restic repository
# Set env vars
export RESTIC_REPOSITORY="b2:my-vps-backup:vps-name"
export B2_ACCOUNT_ID="your-keyID"
export B2_ACCOUNT_KEY="your-applicationKey"
# Tạo password mạnh và lưu file riêng (chmod 600)
openssl rand -base64 48 | sudo tee /root/.restic-pass > /dev/null
sudo chmod 600 /root/.restic-pass
export RESTIC_PASSWORD_FILE=/root/.restic-pass
# Init repo
sudo -E restic init
Quan trọng: file /root/.restic-pass chứa password mã hóa repo. Mất file này + mất key cũ = không restore được data đã backup. Backup file password ra nhiều nơi: password manager, USB cá nhân, in giấy cất tủ.
Script backup hằng ngày
Tạo /usr/local/bin/backup-vps.sh:
#!/usr/bin/env bash
set -euo pipefail
export RESTIC_REPOSITORY="b2:my-vps-backup:vps-name"
export B2_ACCOUNT_ID="your-keyID"
export B2_ACCOUNT_KEY="your-applicationKey"
export RESTIC_PASSWORD_FILE=/root/.restic-pass
TS=$(date +%F-%H%M)
DUMP_DIR=/var/backups/dumps
mkdir -p "$DUMP_DIR"
# 1. Dump Postgres
if command -v pg_dumpall >/dev/null 2>&1; then
sudo -u postgres pg_dumpall > "$DUMP_DIR/pg-all-$TS.sql"
fi
# 2. Dump MySQL/MariaDB
if [ -f /root/.my.cnf ]; then
mysqldump --all-databases > "$DUMP_DIR/mysql-all-$TS.sql"
fi
# 3. Tar wp-content uploads (nếu có)
if [ -d /var/www/html/wp-content/uploads ]; then
tar -czf "$DUMP_DIR/wp-uploads-$TS.tar.gz" -C /var/www/html/wp-content uploads
fi
# 4. Backup paths
restic backup
--tag daily
--tag "$TS"
--exclude '/var/cache'
--exclude '/var/log/*.gz'
--exclude '/tmp'
/etc
/home
/srv
/var/www
/var/backups/dumps
# 5. Retention: 7 daily, 4 weekly, 12 monthly
restic forget --tag daily
--keep-daily 7
--keep-weekly 4
--keep-monthly 12
--prune
# 6. Cleanup local dumps quá 2 ngày
find "$DUMP_DIR" -type f -mtime +2 -delete
# 7. Verify
restic check --read-data-subset=5%
echo "Backup done at $(date)"
Cấp quyền: sudo chmod +x /usr/local/bin/backup-vps.sh. Test chạy thử bằng sudo /usr/local/bin/backup-vps.sh. Lần đầu chậm (upload toàn bộ), lần sau nhanh nhờ dedupe.
Systemd timer mỗi đêm 2h
Tạo 2 file. Đầu tiên unit service:
# /etc/systemd/system/backup-vps.service
[Unit]
Description=Daily VPS backup with restic
After=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup-vps.sh
StandardOutput=append:/var/log/backup-vps.log
StandardError=append:/var/log/backup-vps.err
Nice=10
IOSchedulingClass=idle
Tiếp theo timer:
# /etc/systemd/system/backup-vps.timer
[Unit]
Description=Daily VPS backup timer
[Timer]
OnCalendar=*-*-* 02:00:00
RandomizedDelaySec=30m
Persistent=true
[Install]
WantedBy=timers.target
sudo systemctl daemon-reload
sudo systemctl enable --now backup-vps.timer
# Kiểm tra
systemctl list-timers backup-vps.timer
RandomizedDelaySec 30m giúp tránh nhiều VPS cùng hit B2 lúc 2h sáng (đỡ rate limit). Persistent=true đảm bảo nếu VPS down lúc trigger, sẽ chạy ngay khi up lại.
Test restore: bước quan trọng nhất
Backup không test restore = vô dụng. Mỗi quý làm 1 lần:
# Liệt kê snapshot
restic snapshots
# Mount snapshot mới nhất vào folder để browse
mkdir -p /mnt/restic
restic mount /mnt/restic &
# Browse /mnt/restic/snapshots/latest
ls /mnt/restic/snapshots/latest/etc/nginx
# Restore vào folder test
mkdir -p /tmp/restore-test
restic restore latest --target /tmp/restore-test --include /etc/nginx
# Verify file restore khớp với /etc/nginx hiện tại
diff -r /tmp/restore-test/etc/nginx /etc/nginx
# Cleanup
fusermount -u /mnt/restic
rm -rf /tmp/restore-test
Restore Postgres: load file dump.sql vào psql. Restore wp-content: untar vào folder. Test trên VPS khác (staging) để đảm bảo có thể đứng lên hoàn chỉnh từ backup.
Cost ước tính
| Mục | Đơn giá | Tháng |
|---|---|---|
| Storage 50 GB (sau dedupe) | ~6 USD/TB/tháng | 0.30 USD |
| API calls (~10k/tháng) | Free 2500/ngày, sau đó rẻ | 0 USD |
| Download (test restore quý) | Free 3x storage/tháng | 0 USD |
| Tổng | ~0.3-1 USD/tháng |
Cho VPS 100 GB chỉ tốn dưới 1 USD/tháng. Cho 1 TB tốn 6-8 USD/tháng. So với snapshot VPS provider (thường tính 0.005-0.01 USD/GB/tháng), B2 rẻ hơn 5-10x, lại có versioning và off-provider.
Bảo mật quan trọng
- Password file restic phải chmod 600, chỉ root đọc.
- B2 application key giới hạn chỉ 1 bucket, không global, không master.
- Lưu password và key vào ít nhất 2 nơi off-server (password manager, USB encrypted).
- Bật B2 Object Lock cho retention compliance nếu cần (ransomware protection).
- Backup file /root/.restic-pass + B2 key vào HSM hoặc Vault nếu enterprise.
- Test khả năng restore khi không có quyền truy cập VPS gốc (giả lập VPS bị phá).
Monitoring và alert
- Healthchecks.io ping mỗi lần backup chạy xong, alert nếu skip 2 ngày.
- Telegram bot gửi message tóm tắt mỗi sáng: snapshot size, duration, errors.
- Log tổng cộng vào ELK/Loki để query lịch sử backup.
- Cron job hằng tuần chạy
restic checkfull để verify integrity. - Alert disk B2: monthly bill vượt ngưỡng 2x baseline (dấu hiệu data bloat).
Bẫy thường gặp
| Triệu chứng | Cách fix |
|---|---|
| Backup chậm bất ngờ | Thiếu cache, set $RESTIC_CACHE_DIR vào SSD nhanh |
| B2 rate limit 429 | Restic auto retry, hoặc set --limit-upload để chia tải |
| Quên password = mất data | Backup password ra USB và password manager ngay từ đầu |
| Repo size phình to | Quên prune sau forget, chạy restic prune định kỳ |
| Restore Postgres lỗi sequence | Dùng pg_dumpall thay pg_dump để bao sequence và role |
VPS có snapshot 1-click + restic backup off-provider an toàn 2 lớp
Cloud VPS TND sẵn AlmaLinux 9, Ubuntu 22/24, Debian 12/13. SSD CEPH, snapshot 1-click, backup hằng ngày. Cấu hình restic + B2 thêm cho production critical: lớp 1 snapshot VPS (rollback nhanh), lớp 2 restic offsite (chống provider lock-in).
Xem 8 cấu hình Cloud VPS →FAQ
So với rsync + cron thì restic hơn gì?
Rsync copy file thô, không dedupe global, không snapshot atomic, không encrypt. Restic dedupe block (file 1 GB sửa 1 KB chỉ upload 1 KB), snapshot mỗi lần backup là 1 thời điểm độc lập, encrypt mặc định. Restic dùng hơn 1 file storage rsync khoảng 1.5x ban đầu nhưng tiết kiệm cực nhiều khi 100 snapshot rotation.
Có thể backup nhiều VPS vào cùng 1 repo restic không?
Có. Dùng --host vps-name để tag mỗi backup theo host. Snapshot list sẽ phân biệt theo host. Lợi: dedupe chéo giữa các VPS (vd cùng OS, cùng base image), tiết kiệm dung lượng. Hại: 1 VPS bị compromise có thể delete snapshot của VPS khác nếu key bị leak. Tradeoff: nhỏ vài VPS - 1 repo OK, nhiều VPS quan trọng - tách repo.
Nếu Backblaze bị hack thì sao?
Data đã encrypt AES-256 client-side, B2 không biết key. Kẻ tấn công lấy data về cũng không decrypt được. Tuy nhiên họ có thể xoá file. Mitigation: bật B2 Object Lock (file immutable trong N ngày), bật versioning, hoặc replica sang storage thứ 2 (R2, Wasabi) hằng tuần bằng rclone copy. Đảm bảo 3-2-1: 3 bản, 2 media, 1 offsite.
Có thể restore từ B2 sang VPS mới ở provider khác không?
Hoàn toàn được. Cài restic trên VPS mới, set RESTIC_REPOSITORY và RESTIC_PASSWORD_FILE giống cũ, gọi restic restore latest --target /. Sau đó restore Postgres dump, point DNS, app chạy lại. Đây là chiến lược disaster recovery chuẩn.
Cost B2 có tăng đột biến không?
Hiếm. Pricing B2 dự đoán được: storage charge theo GB/tháng, download free 3x storage. Nếu test restore lớn vượt free quota, charge 0.01 USD/GB. Đặt billing alert 5-10 USD/tháng để biết sớm. Backup VPS hằng ngày cho 100 GB cost ổn định dưới 1 USD/tháng nhiều năm.



