Security

Xây dựng chiến lược sao lưu và phục hồi dữ liệu VPS hiệu quả

Bạn vừa SSH vào VPS và nhận ra toàn bộ dữ liệu đã biến mất. Không phải do hacker, không phải do lỗi phần cứng, mà do bạn chạy nhầm lệnh rm -rf hoặc ghi đè file cấu hình. Không có bản sao lưu nào, mọi thứ bắt đầu lại từ con số không. Câu chuyện này lặp lại thường xuyên hơn bạn nghĩ, và hầu hết đều có thể tránh được nếu có một chiến lược sao lưu và phục hồi dữ liệu VPS được xây dựng từ trước. Bài viết này sẽ hướng dẫn bạn xây dựng chiến lược đó một cách bài bản, áp dụng được ngay trên VPS Linux.

Yêu cầu trước khi bắt đầu

  • Một VPS Linux với quyền root hoặc user có quyền sudo. Hướng dẫn này áp dụng cho Ubuntu 24.04, Debian 12, AlmaLinux 9.
  • Hiểu cơ bản về dòng lệnh, SSH, cấu trúc thư mục trên Linux.
  • Một nơi lưu trữ backup offsite: VPS thứ hai, object storage S3, hoặc dịch vụ lưu trữ đám mây.
  • Biết rõ ứng dụng đang chạy trên VPS (WordPress, n8n, GitLab, Docker...) để backup đúng dữ liệu.

Vì sao chiến lược sao lưu quan trọng hơn việc chạy lệnh backup

Nhiều người quản trị VPS nghĩ sao lưu chỉ đơn giản là nén thư mục và tải về máy. Cách làm đó thiếu sót ở ba điểm: không có lịch trình tự động, không kiểm tra bản backup có khôi phục được không, và không có bản sao ở nơi khác. Một chiến lược đúng nghĩa phải trả lời được bốn câu hỏi: backup cái gì, backup bằng công cụ nào, backup khi nào, và làm sao biết bản backup dùng được.

Với VPS chạy ứng dụng thực tế, dữ liệu không chỉ nằm trong file. Database MySQL/MariaDB, PostgreSQL cần backup theo cách riêng để đảm bảo tính nhất quán. Cấu hình Docker, volume, biến môi trường cũng phải nằm trong kế hoạch. Bỏ sót một thành phần là lúc phục hồi sẽ thất bại.

Bước 1 - Xác định dữ liệu cần sao lưu trên VPS

Trước khi chạy bất kỳ lệnh backup nào, hãy liệt kê chính xác những gì đang tồn tại trên VPS. Mở terminal và kiểm tra dung lượng cũng như các thư mục quan trọng.

df -h
ls -la /var/www
ls -la /etc/nginx
ls -la /etc/letsencrypt
docker volume ls 2>/dev/null
systemctl list-units --type=service --state=running

Những thứ gần như luôn phải backup trên VPS:

  • Mã nguồn website/ứng dụng: thường nằm ở /var/www, /srv, hoặc /home.
  • Database: MySQL/MariaDB (/var/lib/mysql), PostgreSQL (/var/lib/postgresql). Không copy thư mục dữ liệu thô khi database đang chạy, dễ hỏng.
  • File cấu hình: /etc/nginx, /etc/apache2, /etc/ssh, /etc/letsencrypt (SSL certificate).
  • Cron job: /etc/crontab và các file trong /etc/cron.d.
  • Docker: toàn bộ docker-compose.yml, file .env, volume dữ liệu.

Ví dụ với VPS chạy WordPress, cấu trúc backup rõ ràng gồm thư mục /var/www/html và database trong MySQL. Với VPS chạy n8n bằng Docker, cần backup volume chứa dữ liệu workflow và file .env chứa encryption key. Thiếu encryption key mà chỉ có database thì không khôi phục được credential.

Bước 2 - Chọn công cụ sao lưu phù hợp

Không có công cụ nào tối ưu cho mọi trường hợp. Với VPS nhỏ, sự kết hợp giữa snapshot của nhà cung cấp và công cụ backup cấp file là phương án cân bằng nhất.

Snapshot từ nhà cung cấp VPS

Snapshot là bản sao toàn bộ ổ đĩa tại một thời điểm, do hạ tầng ảo hóa KVM tạo ra. Ưu điểm lớn nhất là phục hồi nhanh, đưa VPS về trạng thái đúng lúc chụp. Nhưng snapshot thường nằm trên cùng hạ tầng với VPS, nên không bảo vệ bạn khỏi sự cố ở tầng datacenter. Dùng snapshot như lớp backup đầu tiên, không phải lớp riêng biệt.

Công cụ backup cấp file: rsync và restic

Rsync có sẵn trên mọi bản Linux, đơn giản và hiệu quả cho việc đồng bộ thư mục. Câu lệnh cơ bản:

rsync -avz --delete /var/www/ user@backup-server:/backup/www/
rsync -avz /etc/nginx/ user@backup-server:/backup/nginx/
rsync -avz /etc/letsencrypt/ user@backup-server:/backup/letsencrypt/

Restic mạnh hơn với mã hóa tích hợp, deduplication (chỉ lưu phần dữ liệu thay đổi), và hỗ trợ nhiều backend như S3, SFTP, thư mục local. Đáng đầu tư thời gian nếu bạn cần backup nhiều VPS hoặc dữ liệu lớn. Cài đặt restic trên Ubuntu 24.04 bằng lệnh:

apt install restic -y

Khởi tạo repository và chạy backup lên S3 tương thích:

export RESTIC_PASSWORD="chuoi-mat-khau-manh"
export AWS_ACCESS_KEY_ID="your-key"
export AWS_SECRET_ACCESS_KEY="your-secret"
restic init --repo s3:https://s3.example.com/backup-vps
restic backup /var/www --repo s3:https://s3.example.com/backup-vps

Backup database đúng cách

Với MySQL/MariaDB, dùng mysqldump để xuất dữ liệu thành file SQL trước khi nén:

mysqldump -u root -p --all-databases | gzip > /backup/mysql-$(date +%F).sql.gz

Với PostgreSQL, dùng pg_dump:

su - postgres -c "pg_dumpall" | gzip > /backup/postgres-$(date +%F).sql.gz

Không copy trực tiếp thư mục /var/lib/mysql khi service đang chạy. Dữ liệu ghi dở sẽ khiến database không mở được sau khi khôi phục.

Bước 3 - Xây dựng lịch trình sao lưu tự động

Thiết lập cron job để backup chạy tự động theo lịch. Quy tắc chung: database backup hằng ngày, file dữ liệu hằng ngày, snapshot hằng tuần, và giữ bản backup tháng để đối phó với việc xóa nhầm từ lâu.

Mở crontab của root:

crontab -e

Thêm các dòng lịch sau:

# Backup database lúc 2h sáng mỗi ngày
0 2 * * * /usr/local/bin/backup-database.sh
# Đồng bộ file lên server backup lúc 3h sáng mỗi ngày
0 3 * * * /usr/local/bin/backup-files.sh
# Chạy restic backup lúc 4h sáng mỗi ngày
0 4 * * * /usr/local/bin/restic-backup.sh

Kiểm tra cron đã được cài đặt:

crontab -l

Khi tạo script backup, nhớ thêm biến set -e để script dừng ngay khi có lỗi, tránh tạo bản backup hỏng mà vẫn báo thành công. Ví dụ script /usr/local/bin/backup-database.sh:

#!/bin/bash
set -e
BACKUP_DIR="/backup/database"
mkdir -p "$BACKUP_DIR"
mysqldump -u root -p"$MYSQL_PASSWORD" --all-databases | gzip > "$BACKUP_DIR/mysql-$(date +%F).sql.gz"
find "$BACKUP_DIR" -name "*.sql.gz" -mtime +14 -delete
echo "Database backup hoàn tất $(date)"

Nhớ cấp quyền thực thi cho script:

chmod +x /usr/local/bin/backup-database.sh

Bước 4 - Lưu bản sao offsite và đảm bảo an toàn

Lưu backup trên chính VPS không khác gì không backup. Nếu VPS hỏng ổ cứng hoặc bị tấn công mã hóa dữ liệu, mọi bản sao trên cùng máy đều biến mất. Bản backup phải nằm ở nơi khác: VPS thứ hai, object storage S3, hoặc ổ cứng gắn ngoài.

Quy tắc 3-2-1 áp dụng tốt cho VPS: 3 bản sao dữ liệu, 2 phương tiện lưu trữ khác nhau (ví dụ snapshot và file backup), 1 bản ở vị trí địa lý khác. Thực tế với VPS cá nhân, tối thiểu nên có snapshot tại nhà cung cấp và một bản backup tải về máy hoặc lên object storage.

Rclone là công cụ phổ biến để đẩy backup lên Google Drive, S3, hoặc nhiều dịch vụ đám mây khác. Cài đặt và cấu hình:

apt install rclone -y
rclone config

Sau khi cấu hình xong remote, đồng bộ thư mục backup:

rclone sync /backup remote:backup-vps --verbose

Mã hóa dữ liệu trước khi tải lên là bắt buộc nếu backup chứa thông tin nhạy cảm. Restic đã tích hợp mã hóa sẵn. Với rsync lên server khác, dùng SSH với key để đảm bảo đường truyền an toàn, hoặc nén kèm mật khẩu bằng GPG.

Bước 5 - Kiểm tra khôi phục định kỳ

Bản backup không kiểm tra được thì không có giá trị. Lỗi phổ biến nhất là backup chạy đều đặn nhưng không thể khôi phục, do file hỏng, script lỗi, hoặc thiếu thành phần. Mỗi tháng, dành 30 phút để thực hiện kiểm tra khôi phục trên một VPS tạm hoặc môi trường local.

Quy trình kiểm tra cơ bản:

  1. Giải nén bản backup database mới nhất.
  2. Import thử vào một database tạm: mysql -u root -p -e "CREATE DATABASE test_restore" rồi import file SQL vào database này.
  3. Kiểm tra số bản ghi và dữ liệu quan trọng có khớp không.
  4. Giải nén file website và so sánh tổng số file với bản gốc: find /backup/www -type f | wc -l.
  5. Với Docker, thử chạy docker-compose up với volume đã khôi phục trên máy khác.

Ghi nhận kết quả kiểm tra vào một file log để theo dõi. Nếu phát hiện lỗi, sửa ngay script backup chứ không đợi đến lúc cần khôi phục thật.

Bước 6 - Xử lý lỗi thường gặp khi sao lưu

Bản backup database bị hỏng hoặc không import được

Nguyên nhân thường do database đang ghi dữ liệu khi chạy mysqldump, hoặc file nén bị đứt giữa chừng. Kiểm tra bằng lệnh:

gzip -t /backup/database/mysql-2026-01-15.sql.gz
mysql -u root -p -e "SHOW DATABASES" < /backup/database/mysql-2026-01-15.sql

Nếu file lỗi, chạy lại backup và kiểm tra dung lượng file có hợp lý không. Thêm --single-transaction vào lệnh mysqldump khi dùng InnoDB để có bản backup nhất quán.

Rsync không hoàn tất do mất kết nối mạng

Rsync không có cơ chế retry tự động. Giải pháp là chạy trong script có vòng lặp, hoặc dùng rsync --partial --append-verify để tiếp tục từ điểm dừng:

rsync -avz --partial --append-verify /var/www/ user@backup-server:/backup/www/

Dung lượng backup tăng nhanh

Kiểm tra thư mục backup bằng du -sh /backup/* để xác định thành phần chiếm nhiều dung lượng. Áp dụng chính sách giữ bản backup theo vòng quay: giữ backup 7 ngày gần nhất, 4 tuần gần nhất, 12 tháng gần nhất. Script dùng find + -mtime +N -delete để tự động dọn bản cũ.

Xây dựng kế hoạch phục hồi chi tiết

Có backup nhưng không có quy trình phục hồi rõ ràng thì lúc xảy ra sự cố vẫn luống cuống. Viết một tài liệu recovery runbook với các bước cụ thể: SSH vào VPS mới, cài đặt các gói cần thiết, khôi phục file từ backup, import database, khởi động service và kiểm tra. Ví dụ tài liệu phục hồi cho VPS WordPress:

# 1. Cài đặt Nginx, PHP, MariaDB
apt update && apt install nginx php-fpm php-mysql mariadb-server -y
# 2. Giải nén file website
rsync -avz user@backup-server:/backup/www/ /var/www/html/
# 3. Import database
mysql -u root -p -e "CREATE DATABASE wordpress"
mysql -u root -p wordpress < /backup/database/wordpress.sql
# 4. Cấu hình Nginx và khởi động
systemctl restart nginx php8.3-fpm
systemctl status nginx

Lưu runbook này ở nơi không phụ thuộc vào VPS, ví dụ Google Docs hoặc file trên máy cá nhân. Khi VPS hỏng hoàn toàn, bạn vẫn đọc được tài liệu và làm theo từng bước.

Câu hỏi thường gặp

Bao lâu nên chạy backup một lần?

Database nên backup hằng ngày vì dữ liệu thay đổi liên tục. File website có thể backup hằng ngày hoặc cách ngày tùy tần suất cập nhật. Snapshot tối thiểu mỗi tuần, đặc biệt trước khi thực hiện thay đổi lớn như nâng cấp hệ điều hành hoặc cài phần mềm mới.

Snapshot của nhà cung cấp có đủ để bảo vệ dữ liệu không?

Chưa đủ. Snapshot nằm trên cùng hạ tầng với VPS, không bảo vệ khỏi sự cố ở tầng datacenter hoặc lỗi logic như xóa nhầm dữ liệu từ nhiều tuần trước. Kết hợp snapshot với backup cấp file đẩy sang nơi khác là phương án an toàn nhất.

Lưu backup trên VPS giá rẻ thứ hai có tốt không?

Được, đó là cách phổ biến và tiết kiệm. Một VPS Linux giá rẻ chỉ để lưu backup, cài SSH và rsync là đủ. Chỉ cần đảm bảo VPS này ở trung tâm dữ liệu khác hoặc nhà cung cấp khác với VPS chính để tránh rủi ro cùng lúc.

Restic hay rsync nên chọn công cụ nào?

Rsync đơn giản, có sẵn, dễ gỡ lỗi, phù hợp khi backup ít thay đổi và dung lượng nhỏ. Restic mạnh hơn nhờ mã hóa, deduplication, hỗ trợ nhiều backend, phù hợp khi dữ liệu lớn hoặc cần backup nhiều VPS. Nếu mới bắt đầu, dùng rsync trước, nâng cấp lên restic khi cần.

Có cần backup toàn bộ ổ đĩa VPS không?

Không cần. Chỉ backup dữ liệu quan trọng: mã nguồn, database, file cấu hình, cron job. Toàn bộ hệ điều hành có thể cài lại nhanh, còn dữ liệu thì không. Backup toàn bộ ổ đĩa tốn dung lượng mà ít giá trị thực tế hơn so với backup có chọn lọc.

Làm sao biết bản backup hoạt động tốt?

Cách riêng biệt là kiểm tra khôi phục định kỳ. Mỗi tháng một lần, thử import database và giải nén file trên môi trường tạm. Kiểm tra log backup hằng tuần để phát hiện lỗi sớm. Backup chạy nhưng không kiểm tra thì vẫn có thể thất bại lúc cần đến.

Bài viết liên quan

Lưu ý: Bài viết mang tính tham khảo, tổng hợp kiến thức chung. Mỗi hệ thống, hạ tầng và nhu cầu có đặc thù riêng, nên kiểm thử trong môi trường an toàn và tham vấn kỹ sư trước khi triển khai thực tế.