- 先使用 rclone 将 onedrive 挂载到机器中,在最后一步时选择使用 remote(即选择 N),再到 PC 上使用 rclone 进行验证(相关教程自行搜索)
- 将 rclone 挂载到对应的路径下,如
/mnt/onedrive,如果不挂载在这个目录,则需要修改脚本中的BACKUP_BASE_DIR - 设置对应的 脚本,设置执行权限
chmod +x /opt/data/scripts/backup.sh,并设置定时任务0 4 * * * /bin/bash /opt/data/scripts/backup.sh(临晨四点进行)
脚本
#!/bin/bash
# 配置文件目录和文件
CONFIG_DIR="${HOME}/.config/backup"
CONFIG_FILE="${CONFIG_DIR}/server_name"
BACKUP_BASE_DIR="/mnt/onedrive/backup/docker"
# 确保配置目录存在
mkdir -p "$CONFIG_DIR"
# 函数:检查服务器名是否已存在
check_server_name() {
local name=$1
if [-d "${BACKUP_BASE_DIR}/${name}" ]; then
return 0 # 存在返回 0
else
return 1 # 不存在返回 1
fi
}
# 函数:获取服务器名称
get_server_name() {local default_name=$(hostname) # 使用主机名作为默认名称
local server_name=""
while true; do
read -p " 请输入服务器名称 [默认: $default_name]: " server_name
# 如果用户直接回车,使用默认名称
if [-z "$server_name"]; then
server_name=$default_name
fi
# 检查服务器名是否已存在
if check_server_name "$server_name"; then
printf " 警告:发现同名服务器 '%s'\n" "$server_name" >&2 # 将警告信息输出到标准错误
while true; do
read -p " 是否继续使用此名称?(Y/N) " continue_use
case $continue_use in
[Yy])
printf "%s" "$server_name" # 只输出服务器名称到标准输出
return
;;
[Nn])
break # 退出内部循环,重新输入名称
;;
*)
echo " 无效的输入,请输入 Y 或 N" >&2
;;
esac
done
else
# 名称不存在,直接使用
printf "%s" "$server_name"
return
fi
done
}
# 检查是否已设置服务器名
if [! -f "$CONFIG_FILE"]; then
# 获取服务器名称并保存到配置文件
SERVER_NAME=$(get_server_name)
echo " 使用服务器名称: $SERVER_NAME"
echo "$SERVER_NAME" > "$CONFIG_FILE"
chmod 600 "$CONFIG_FILE" # 设置文件权限,只允许所有者读写
else
# 读取已存在的服务器名
SERVER_NAME=$(cat "$CONFIG_FILE")
echo " 使用服务器名称: $SERVER_NAME"
fi
# 1. 关闭所有 Docker 容器
echo "
正在关闭所有容器,请稍候...
Stopping all Docker containers..."
docker stop $(docker ps -q)
# 2. 打包压缩 /opt/data/appdata/ 目录
echo "
正在打包所有容器,请稍候...
Compressing /opt/data/appdata/..."
backup_dir="/opt/data/appdata"
backup_file="/tmp/appdata_backup.tar.gz"
tar -czf $backup_file -C $backup_dir .
# 3. 转移压缩包到 /mnt/onedrive/backup/docker/$SERVER_NAME
backup_destination="${BACKUP_BASE_DIR}/${SERVER_NAME}"
mkdir -p "$backup_destination"
mv "$backup_file" "$backup_destination"
# 4. 给压缩包按新命名规则命名: yyyymmdd_hhmmss_$SERVER_NAME.tar.gz
timestamp=$(date +"%Y%m%d_%H%M%S")
new_backup_name="${timestamp}_${SERVER_NAME}.tar.gz"
mv "${backup_destination}/$(basename $backup_file)" "${backup_destination}/${new_backup_name}"
# 5. 如果 /mnt/onedrive/backup/docker/$SERVER_NAME 下已有 25 个 .tar.gz 文件, 删除最早的一个
echo "
检测是否有多余 25 个备份文件
Cleaning up old backups if more than 25 exist..."
cd "$backup_destination"
backup_count=$(ls *.tar.gz 2>/dev/null | wc -l)
if ["$backup_count" -ge 25]; then
# 找到最早的一个并删除
oldest_backup=$(ls -1t *.tar.gz | tail -n 1)
echo " 检测到备份文件超出 25 个,正在删除...
Deleting oldest backup: $oldest_backup"
rm -f "$oldest_backup"
fi
# 6. 重启 Docker 容器
echo "
重启所有容器
Starting all Docker containers..."
docker start $(docker ps -a -q)
echo "
备份成功
Backup completed successfully."
正文完