使用BorgBackup备份数据
我之前一直使用Duplicati 备份各种数据,但是因为这个软件一直在Beta, 经常性的出问题,漏文件,备份失败之类的。 于是我决定完全切换到BorgBackup,一个命令行基于SSH的client-server模式的备份解决方案。
首先我们需要在备份服务器上面安装Borg服务端,很简单,例如我用debian, 于是只需要运行下面的命令即可:
sudo apt update
sudo apt install borgbackup #安装
sudo useradd -m -s /bin/bash borg-backup #创建独立的用户,这个用户用来运行borg相关进程,你可以换个用户名
sudo passwd borg-backup #设置密码
sudo mkdir -p /backup/repos #创建备份仓库目录
sudo chown borg-backup:borg-backup /backup/repos #修改仓库的所有者
至此服务端(Server)就基本搭好了,接下来需要在客户端(即需要备份的机器)执行:
su #切换到root,因为我需要备份一些需要root才能读取的数据
apt install borgbackup
ssh-keygen -t ed25519 #生成用于远程登录的ssh key
ssh-copy-id borg-backup@server-ip #把公钥复制到服务端
ssh登录的安全问题可以在服务端(server)上的把下面这段复制到authorized_keys 中每一个公钥前面:
command="borg serve --restrict-to-path /backup/repos",restrict
例如:
command="borg serve --restrict-to-path /backup/repos",restrict ssh-ed25519 AAAAC3NzaC1lZDI1N... root@client
这段内容给borg-backup用户设置一个限制,即他使用ssh只能运行borg server命令,并且它只能读写/backup/repos目录。
至此我们的服务器和客户端就安装设置好了,接下来我们需要在客户端运行下面的命令以创建一个备份仓库:
borg init -e repokey-blake2 ssh://borg-backup@ip/backup/repos/[仓库名]
跟着写一个bash脚本,并把它放到crontab里面即可以完成自动备份了。
这里附一个我自用的脚本:
#!/bin/bash
# Borg settings
export BORG_REPO='ssh://borg-backup@ip:port/backup/repos/gl-win2'
export BORG_PASSPHRASE='repo password here'
# Parse command line arguments
# --with-mysql will use mysqldump to create a mysql backup
BACKUP_MYSQL=false
while [[ $# -gt 0 ]]; do
case $1 in
--with-mysql)
BACKUP_MYSQL=true
shift
;;
*)
echo "Unknown option: $1"
echo "Usage: $0 [--with-mysql]"
exit 1
;;
esac
done
# Handle MySQL backup if requested
if [ "$BACKUP_MYSQL" = true ]; then
echo "Starting MySQL backup..."
BACKUP_DIR="/tmp/mysql_backup"
mkdir -p $BACKUP_DIR
mysqldump -u root -p'mysql database password' --all-databases --single-transaction > $BACKUP_DIR/all_databases.sql
echo "MySQL backup completed"
fi
# Common exclusion patterns
EXCLUDE_PATTERNS=(
'/home/**/.cache/**'
'**/*.pyc'
'/var/lib/docker/volumes/**/._*'
'/var/lib/docker/overlay2/**' # Docker images
'/var/lib/docker/image/**' # Docker image metadata
'/var/lib/docker/containers/**' # Docker container data
'**/go/pkg/mod/**'
'**/node_modules/**'
'**/.git/**'
'**/vendor/**'
'**/*.log'
'**/*.log.gz'
'**/podsync/data/**'
'/home/**/.npm/**'
'/home/**/.cargo/**'
'/home/**/.rustup/**'
'**/__pycache__/**'
'**/tmp/**'
'/var/log/**'
'/var/cache/**'
'**/.idea/**'
'**/.vscode/**'
'**/build/**'
'**/dist/**'
'**/pihole-FTL.db'
'**/venv/**' # Python virtual environments
'**/env/**' # Another common Python venv name
'/home/**/.local/lib/python**/**' # User-installed Python packages
'/usr/local/lib/python**/**' # System Python packages
'/usr/lib/python**/**' # System Python packages
'**/*.pyc' # Python compiled files
'**/*.pyo' # Python optimized files
'**/*.pyd' # Python DLL files
'**/.pytest_cache/**' # Pytest cache
'**/site-packages/**' # Python site-packages
'**/dist-packages/**' # Debian/Ubuntu Python packages
)
# Build exclude arguments
EXCLUDE_ARGS=""
for pattern in "${EXCLUDE_PATTERNS[@]}"; do
EXCLUDE_ARGS="$EXCLUDE_ARGS --exclude '$pattern'"
done
# Create backup command
BACKUP_PATHS="/home /var/lib/docker/volumes" # backup source folders
if [ "$BACKUP_MYSQL" = true ]; then
BACKUP_PATHS="$BACKUP_PATHS /tmp/mysql_backup"
fi
# Execute borg create with all exclusions
eval borg create \
--verbose \
--filter AME \
--list \
--stats \
--compression lz4 \
::'client-machine-name-{now}' \
$BACKUP_PATHS \
$EXCLUDE_ARGS
# Clean up MySQL dump if it exists
if [ "$BACKUP_MYSQL" = true ]; then
rm -rf /tmp/mysql_backup
fi
# Prune old backups
borg prune \
--keep-daily 7 \
--keep-weekly 4 \
--keep-monthly 6
echo "Backup completed at $(date)" >> /var/log/borg-backup.log