Nhiều năm qua, công cụ sao lưu dữ liệu website yêu thích của mình là UpdraftPlus. Tất cả các website WordPress của mình đều không thể thiếu plugin UpdraftPlus để sao lưu dữ liệu và database.
Ưu điểm của UpdraftPlus là dễ sử dụng, dễ tùy biến, setup 1 lần rồi quên luôn. Bao giờ có biến mới cần đụng đến.
Tuy nhiên, UpdraftPlus có khá nhiều nhược điểm:
- Phải tốn tiền mua bản Premium mới dùng được các tính năng cao cấp. Mình đang dùng gói $95 / năm (10 websites)
- Chỉ dùng được cho WordPress, không dùng cho các dự án web khác.
- Dữ liệu được zip trước khi upload lên backup server, tăng tác vụ cho CPU của VPS
- Dữ liệu mỗi ngày được sao lưu riêng biệt, gây hao tốn dung lượng ổ cứng lưu trữ.
Do đó, mình phải nghiên cứu một công cụ backup khác để phục vụ cho nhu cầu sử dụng trong tương lai. Yêu cầu phải đáp ứng các tiêu chí: hoạt động nhanh, ổn định, có tính năng deduplication (chống trùng lặp), và nếu miễn phí thì càng tốt.
Một trong các công cụ thỏa mãn các tiêu chí vừa kể là Borg Backup. Mình đã nghe danh Borg từ lâu, nhưng gần đây mới dành thời gian học cách sử dụng.
Mục Lục
I. Borg là gì?
BorgBackup, hay thường gọi tắt là borg, là một công cụ sao lưu dữ liệu được tối ưu hóa nhờ áp dụng công nghệ deduplication.
Một số tính năng độc đáo của borg:
- Deduplication – Công nghệ chống trùng lặp, chỉ sao lưu những thay đổi so với lần sao lưu trước đó.
- Đa nền tảng – Có thể được cài đặt và sử dụng trên Linux, Mac OS X, và FreeBSD.
- Bảo mật – Hỗ trợ mã hóa AES (256-bit)
- Nén dữ liệu – Hỗ trợ nhiều phương thức né dữ liệu
- LZ4 -> Siêu nhanh, độ nén thấp.
- ZSTD -> Nhiều lựa chọn nén ít, tốc độ nhanh đến nén nhiều, tốc độ chậm.
- ZLIB -> Nén trung bình, tốc độ trung bình.
- LZMA -> Tốc độ chậm, tỉ lệ nén cao.
- Remote backup – Dữ liệu có thể được gửi đến máy chủ khác thông qua giao thức SSH.
Khi sử dụng Borg, có 2 thuật ngữ quan trọng cần phải nhớ:
- Archives – Là bản sao của dữ liệu bạn sao lưu ở một thời điểm nhất định.
- Repositories – Là thư mục để lưu trữ các bản sao lưu archive.
Trong bài viết này mình sẽ hướng dẫn cách sao lưu dữ liệu của blog thuanbui này từ VPS lên Storage Box của Hetzner sử dụng công cụ Borg Backup.
- Archive sẽ là dữ liệu của thư mục
/home/ols-docker-env/sites/thuanbui.me/html/
trên VPS của GreenCloud VPS. - Repository là thư mục
/home/Backup/website/thuanbui.me/data
trên Storage Box của Hetzner.
II. Cài đặt Borg
Cài đặt Borg trên Server và Client bằng một trong các lệnh sau
Ubuntu / Debian
sudo apt install borgbackup -y
Code language: Nginx (nginx)
Fedora, RHEL, CentOS, AlmaLinux and Rocky Linux
sudo dnf install borgbackup
Code language: Nginx (nginx)
Arch / EndavourOS
sudo pacman -S borg
Code language: Nginx (nginx)
Storage Box của Hetzner đã tích hợp sẵn SSH và Borg, nên mình chỉ cần cài lên VPS đang chạy website.
III. Tạo SSH key cho Storage Box
Tiếp theo, để VPS có thể ssh tự động vào Storage Box mà không cần nhập password, mình cần tạo SSH Key và copy qua Storage Box để xác thực.
Truy cập vào VPS và tạo SSH Key mới bằng lệnh
ssh-keygen
SSH Key sẽ được lưu trong thư mục /root/.ssh/
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa
Your public key has been saved in /root/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:11C4qBgfpxxxxxxxxxxxxxxxxkQhpDEfhZA root@GreenCloud.1665799540
The key's randomart image is:
+---[RSA 3072]----+
| . ++o+o |
| . . E23o. |
| odsa ..oo . |
| = = + oo.. |
| Xxxcs..= |
| o = +.=o.. o |
| o =.. + |
| . + .... |
| +oo... |
+----[SHA256]-----+
Code language: Shell Session (shell)
Copy SSH Key vừa tạo lên Storage Box thông qua giao thức SSH
cat ~/.ssh/id_rsa.pub | ssh -p23 uxxxx@uxxxx.your-storagebox.de install-ssh-key
Code language: Nginx (nginx)
Cần nhập password của Storage Box để xác thực. Sau đó SSH Key sẽ được copy qua.
The authenticity of host '[uxxxxxx.your-storagebox.de]:23 ([168.xxx.xxx.181]:23)' can't be established.
ECDSA key fingerprint is SHA256:oDHZqKXxcsdsssdcuFez28roaEuFcfwyg8O5c.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '[uxxxxxx.your-storagebox.de]:23,[168.xxx.xxx.181]:23' (ECDSA) to the list of known hosts.
uxxxxxx@uxxxxxx.your-storagebox.de's password:
Key No. 1 (ssh-rsa root@GreenCloud.1665799540) was installed in RFC4716 format
Key No. 1 (ssh-rsa root@GreenCloud.1665799540) was installed in OpenSSH format
Code language: Shell Session (shell)
Kiểm tra thử SSH Key hoạt động ổn chưa bằng cách ssh vào Storage Box. Nó sẽ tự động kết nối thành công mà không cần nhập password.
ssh -p23 uxxxxx@uxxxxxx.your-storagebox.de
+------------------------------------------------------------------+
| Welcome to your Storage Box. |
| |
| Please note that this is only a restricted shell environment and |
| therefore some shell features like pipes and redirects are not |
| supported. |
+------------------------------------------------------------------+
Code language: Dockerfile (dockerfile)
Mọi thao tác đều được thực hiện trên Borg client – VPS đang chứa dữ liệu.
IV. Khởi tạo Repository
Tạo thư mục mới trên Storage Box dùng làm Repository cho Borg
ssh -p23 uxxxxx@uxxxxxx.your-storagebox.de mkdir -p ./Backup/website/thuanbui.me/data
Code language: Nginx (nginx)
Khởi tọa repository bằng lệnh borg init
. Mình không sử dụng mã hóa nên phần --encryption
chọn none. Bạn nào quan tâm về mã hóa có thể tham khảo thêm ở đây: https://borgbackup.readthedocs.io/en/stable/quickstart.html#repository-encryption
borg init --encryption=none ssh://uxxxxxx@uxxxxx.your-storagebox.de:23/./Backup/website/thuanbui.me/data
Code language: Nginx (nginx)
V. Sao lưu dữ liệu lên Repository
Tạo backup đầu tiên lên repository
borg create --stats --progress ssh://uxxxxxx@uxxxxxx.your-storagebox.de:23/./Backup/website/thuanbui.me/data::'{now:%Y-%m-%d_%H:%M}' /home/ols-docker-env/sites/thuanbui.me/html/
Code language: JavaScript (javascript)
Thời gian backup mất gần 2 phút cho 1.4 GB dữ liệu
------------------------------------------------------------------------------
Archive name: 2024-01-08_13:38
Archive fingerprint: c30dee52fa104c6057f1819312f5dc1c88c17a0a6e5d3c3fb8343cc657ae8b92
Time (start): Mon, 2024-01-08 13:38:30
Time (end): Mon, 2024-01-08 13:40:19
Duration: 1 minutes 49.00 seconds
Number of files: 28879
Utilization of max. archive size: 0%
------------------------------------------------------------------------------
Original size Compressed size Deduplicated size
This archive: 1.62 GB 1.40 GB 1.39 GB
All archives: 1.62 GB 1.40 GB 1.39 GB
Unique chunks Total chunks
Chunk index: 27792 29140
------------------------------------------------------------------------------
Code language: Shell Session (shell)
Sau vài tiếng, mình chạy thêm 1 lệnh backup thêm 1 lần nữa
borg create --stats --progress ssh://uxxxxxx@uxxxxxx.your-storagebox.de:23/./Backup/website/thuanbui.me/data::'{now:%Y-%m-%d_%H:%M}' /home/ols-docker-env/sites/thuanbui.me/html/
Code language: JavaScript (javascript)
Nhờ Borg sử dụng công nghệ deduplication (chống trùng lặp), chỉ sao lưu những thay đổi so với lần backup gần nhất nên lần này thời gian thao tác chỉ mất 3 giây. Tổng dung lượng lưu trữ vẫn giữ nguyên 1.4 GB.
------------------------------------------------------------------------------
Archive name: 2024-01-08_20:42
Archive fingerprint: 531574ac71b574d9ce7884389765f96d0e90567c30e991ce770cfe784726ce96
Time (start): Mon, 2024-01-08 20:42:11
Time (end): Mon, 2024-01-08 20:42:14
Duration: 2.94 seconds
Number of files: 28874
Utilization of max. archive size: 0%
------------------------------------------------------------------------------
Original size Compressed size Deduplicated size
This archive: 1.02 GB 835.14 MB 365.82 kB
All archives: 2.65 GB 2.24 GB 1.39 GB
Unique chunks Total chunks
Chunk index: 27802 58064
------------------------------------------------------------------------------
Code language: YAML (yaml)
Nếu backup theo cách thông thường, không có deduplication thì chắc chắn sẽ tốn gấp đôi dung lượng: 2.8 GB.
VI. Xem thông tin bản sao lưu
Để liệt kê các bản sao lưu đang có trong repository, dùng lệnh borg list
borg list ssh://uxxxxxx@uxxxxxx.your-storagebox.de:23/./Backup/website/thuanbui.me/data
Code language: PHP (php)
2024-01-08_13:38 Mon, 2024-01-08 20:38:30 [c30dee52fa104c6057f1819312f5dc1c88c17a0a6e5d3c3fb8343cc657ae8b92]
2024-01-08_20:42 Mon, 2024-01-08 20:42:11 [531574ac71b574d9ce7884389765f96d0e90567c30e991ce770cfe784726ce96]
Code language: YAML (yaml)
Xem thông tin chi tiết của từng bản sao lưu bằng lệnh borg info
borg info ssh://uxxxxx@uxxxxxx.your-storagebox.de:23/./Backup/website/thuanbui.me/data::2024-01-08_20:42
Code language: Nginx (nginx)
Kết quả trả về
Utilization of maximum supported archive size: 0%
------------------------------------------------------------------------------
Original size Compressed size Deduplicated size
This archive: 1.02 GB 832.96 MB 365.82 kB
All archives: 2.65 GB 2.24 GB 1.39 GB
Unique chunks Total chunks
Chunk index: 27802 58064
Code language: YAML (yaml)
Để xem các file có trong từng bản sao lưu, dùng lệnh borg list
borg list ssh://uxxxxx@uxxxxxx.your-storagebox.de:23/./Backup/website/thuanbui.me/data::2024-01-08_20:42
Code language: PHP (php)
Kết quả trả về tương tự như bên dưới
-rw-r--r-- 1000 1000 1693 Sun, 2022-11-06 13:24:09 home/ols-docker-env/sites/thuanbui.me/html/wp-includes/customize/class-wp-customize-new-menu-section.php
-rw-r--r-- 1000 1000 716 Sun, 2022-11-06 13:24:09 home/ols-docker-env/sites/thuanbui.me/html/wp-includes/customize/class-wp-customize-nav-menu-section.php
-rw-r--r-- 1000 1000 11889 Sun, 2023-11-12 12:18:56 home/ols-docker-env/sites/thuanbui.me/html/wp-includes/customize/class-wp-customize-theme-control.php
-rw-r--r-- 1000 1000 8054 Sun, 2023-11-12 12:18:56 home/ols-docker-env/sites/thuanbui.me/html/wp-includes/customize/class-wp-customize-header-image-control.php
-rw-r--r-- 1000 1000 10568 Sun, 2022-11-06 13:24:09 home/ols-docker-env/sites/thuanbui.me/html/wp-includes/customize/class-wp-customize-partial.php
-rw-r--r-- 1000 1000 6993 Sun, 2022-11-06 13:24:09 home/ols-docker-env/sites/thuanbui.me/html/wp-includes/customize/class-wp-customize-nav-menu-item-control.php
Code language: YAML (yaml)
VII. So sánh 2 bản sao lưu
Sử dụng lệnh borg diff
để so sánh sự khác nhau giữa 2 bản sao lưu
borg diff ssh://uxxxxx@uxxxxx.your-storagebox.de:23/./Backup/website/thuanbui.me/data::2024-01-08_13:38 2024-01-08_20:42
Code language: Nginx (nginx)
Kết quả trả về cho thấy bản backup lúc 20:42 đã xóa đi 5 file so với bản backup lúc 13:38
removed 99.27 MB home/ols-docker-env/sites/thuanbui.me/html/wp-content/updraft/backup_2023-09-10-1726_Thun_Bi_0779a30ec59c-plugins.zip
removed 5.81 MB home/ols-docker-env/sites/thuanbui.me/html/wp-content/updraft/backup_2023-09-10-1726_Thun_Bi_0779a30ec59c-themes.zip
removed 415.27 MB home/ols-docker-env/sites/thuanbui.me/html/wp-content/updraft/backup_2023-09-10-1726_Thun_Bi_0779a30ec59c-uploads.zip
removed 10.29 MB home/ols-docker-env/sites/thuanbui.me/html/wp-content/updraft/backup_2023-09-10-1726_Thun_Bi_0779a30ec59c-others.zip
removed 66.68 MB home/ols-docker-env/sites/thuanbui.me/html/wp-content/updraft/backup_2023-09-10-1726_Thun_Bi_0779a30ec59c-uploads2.zip
Code language: YAML (yaml)
VIII. Phục hồi bản sao lưu
Để phục hồi bản sao lưu, sử dụng lệnh borg extract
. Borg sẽ phục hồi dữ liệu ra thư mục hiện tại.
borg extract -v --list ssh://uxxxxxx@uxxxxxx.your-storagebox.de:23/./Backup/website/thuanbui.me/data::2024-01-08_20:42
Code language: PHP (php)
Nếu chỉ muốn phục hồi một vài thư mục hoặc file nhất định trong bản sao lưu, chúng ta cần bổ sung thêm vào phần cuối của dòng lệnh. Ví dụ: mình chỉ muốn phục hồi thư mục plugins thì sẽ dùng lệnh sau
borg extract -v --list ssh://uxxxxxx@uxxxxxx.your-storagebox.de:23/./Backup/website/thuanbui.me/data::2024-01-08_20:42 home/ols-docker-env/sites/thuanbui.me/html/wp-content/plugins
Code language: PHP (php)
IX. Mount bản sao lưu vào thư mục
Trong trường hợp chỉ muốn copy vài file bất kỳ từ bản sao lưu ra ngoài, chúng ta có thể mount bản sao lưu vào thư mục trên VPS.
Tạo thư mục mới để mount
mkdir /tmp/borg/
Code language: Nginx (nginx)
Mount bản sao lưu vào thư mục vừa tạo
borg mount ssh://uxxxxx@uxxxxx.your-storagebox.de:23/./Backup/website/thuanbui.me/data::2024-01-08_20:42 /tmp/borg
Code language: Nginx (nginx)
Sau đó, mình có thể truy cập vào thư mục /tmp/borg
để thao tác file như bình thường (copy, rsync, cat,…)
Để unmount bản backup ra khỏi VPS, dùng lệnh borg unmount
borg umount /tmp/borg
Code language: Nginx (nginx)
X. Sao lưu tự động bằng cron
Tạo thư mục để lưu log
mkdir -p /var/log/borg
Code language: JavaScript (javascript)
Tạo file bash thuanbui_backup.sh
với nội dung sau
#!/usr/bin/env bash
##
## Set some variables
##
LOG='/var/log/borg/backup.log'
export BACKUP_USER='uxxxxxx'
export REPOSITORY_DIR='Backup/website/thuanbui.me/data'
## Tip: If using with a Backup Space you have to use
## 'your-storagebox.de' instead of 'your-backup.de'
export REPOSITORY="ssh://${BACKUP_USER}@${BACKUP_USER}.your-storagebox.de:23/./${REPOSITORY_DIR}"
##
## Output to a logfile
##
exec > >(tee -i ${LOG})
exec 2>&1
echo "###### Backup started: $(date) ######"
##
## At this place you could perform different tasks
## that will take place before the backup, e.g.
##
## - Create a list of installed software
## - Create a database dump
##
##
## Transfer the files into the repository.
## In this example the folders root, etc,
## var/www and home will be saved.
## In addition you find a list of excludes that should not
## be in a backup and are excluded by default.
##
echo "Transfer files ..."
borg create -v --stats \
$REPOSITORY::'{now:%Y-%m-%d_%H:%M}' \
/home/ols-docker-env/sites/thuanbui.me/html
echo "###### Backup ended: $(date) ######"
Code language: Bash (bash)
Cho chạy thử
chmod u+x thuanbui_backup.sh
./thuanbui_backup.sh
Code language: Nginx (nginx)
Backup chạy thành công
###### Backup started: Tue Jan 9 12:47:34 +07 2024 ######
Transfer files ...
Creating archive at "ssh://uxxxxxx8@uxxxxxx.your-storagebox.de:23/./Backup/website/thuanbui.me/data::{now:%Y-%m-%d_%H:%M}"
Remote: compaction freed about 593 B repository space.
------------------------------------------------------------------------------
Archive name: 2024-01-09_12:47
Archive fingerprint: 9d8914a8857cbc320d5703a02042951e2e1b2dcf76b9d0d5b05e4887bf998b44
Time (start): Tue, 2024-01-09 12:47:41
Time (end): Tue, 2024-01-09 12:47:44
Duration: 3.26 seconds
Number of files: 28874
Utilization of max. archive size: 0%
------------------------------------------------------------------------------
Original size Compressed size Deduplicated size
This archive: 1.02 GB 835.14 MB 2.20 MB
All archives: 3.67 GB 3.07 GB 1.39 GB
Unique chunks Total chunks
Chunk index: 27856 86985
------------------------------------------------------------------------------
###### Backup ended: Tue Jan 9 12:47:46 +07 2024 ######
Code language: YAML (yaml)
Xem lại log sao lưu bằng lệnh sau
cat /var/log/borg/backup.log
Code language: JavaScript (javascript)
###### Backup started: Tue Jan 9 12:47:34 +07 2024 ######
Transfer files ...
Creating archive at "ssh://uxxxxxx@uxxxxxx.your-storagebox.de:23/./Backup/website/thuanbui.me/data::{now:%Y-%m-%d_%H:%M}"
Remote: compaction freed about 593 B repository space.
------------------------------------------------------------------------------
Archive name: 2024-01-09_12:47
Archive fingerprint: 9d8914a8857cbc320d5703a02042951e2e1b2dcf76b9d0d5b05e4887bf998b44
Time (start): Tue, 2024-01-09 12:47:41
Time (end): Tue, 2024-01-09 12:47:44
Duration: 3.26 seconds
Number of files: 28874
Utilization of max. archive size: 0%
------------------------------------------------------------------------------
Original size Compressed size Deduplicated size
This archive: 1.02 GB 835.14 MB 2.20 MB
All archives: 3.67 GB 3.07 GB 1.39 GB
Unique chunks Total chunks
Chunk index: 27856 86985
------------------------------------------------------------------------------
###### Backup ended: Tue Jan 9 12:47:46 +07 2024 ######
Code language: YAML (yaml)
Tiếp theo, tạo cronjob để tự động sao lưu mỗi ngày
crontab -e
Code language: Nginx (nginx)
Bổ sung vào nội dung sau ở cuối file và lưu lại.
0 0 * * * /home/thuanbui_backup.sh > /dev/null 2>&1
Code language: JavaScript (javascript)
Mình sẽ cho scrip backup này chạy vào lúc 00:00 mỗi ngày.
Để hạn chế số lượng bản sao lưu trên repository, bạn có thể bổ sung thêm lệnh borg prune
vào file bash trên. Tuy nhiên, lệnh này sẽ xóa archives ra khỏi repository, do đó không khuyến khích sử dụng nếu chưa nghiên cứu kỹ hướng dẫn của borg ở đây.
Hướng dẫn này chỉ mới thực hiện sao lưu dữ liệu của website, chưa sao lưu database. Bạn nào muốn sao lưu thêm database thì có thể dùng lệnh wp db export
để export database ra thư mục nào đó rồi tạo thêm repository cho database.
Chúc bạn mò borg vui vẻ!
[convertkit form=7087807]
Mình có sử dụng cái storage Hetzner, hỗ trợ nhiều phương thức lưu trữ. Nhưng tốc độ up lên cực thấp. Tầm 3Mbps/s, upload lưu trữ dữ liệu rất lâu.