实现功能: - 文件夹和 MySQL 容器数据库备份 - tar.gz 压缩和自动清理旧备份 - systemd 定时任务集成 - 远程一键安装脚本(通过 Gitea 仓库) - 完整的 llmdoc 文档系统 安装方式: bash <(curl -sL https://gitea.bcde.io/wangdefa/docker-backup/raw/branch/main/install.sh) 配置文件位置:/etc/docker-backup/config.yml 命令:docker-backup, docker-backup-cleanup
250 lines
7.6 KiB
Bash
Executable File
250 lines
7.6 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
###############################################################################
|
|
# Docker Backup Cleanup Script
|
|
# 功能:清理旧的备份文件
|
|
###############################################################################
|
|
|
|
set -e
|
|
set -o pipefail
|
|
|
|
# 脚本所在目录
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
|
|
# 配置文件路径(系统级配置)
|
|
CONFIG_FILE="${CONFIG_FILE:-/etc/docker-backup/config.yml}"
|
|
|
|
# 颜色输出
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
NC='\033[0m'
|
|
|
|
###############################################################################
|
|
# 日志函数
|
|
###############################################################################
|
|
|
|
log_info() {
|
|
echo -e "${GREEN}[INFO]${NC} $@"
|
|
}
|
|
|
|
log_warn() {
|
|
echo -e "${YELLOW}[WARN]${NC} $@"
|
|
}
|
|
|
|
log_error() {
|
|
echo -e "${RED}[ERROR]${NC} $@"
|
|
}
|
|
|
|
###############################################################################
|
|
# 检查依赖
|
|
###############################################################################
|
|
|
|
check_dependencies() {
|
|
if ! command -v yq &> /dev/null; then
|
|
log_error "缺少依赖工具: yq"
|
|
log_error "请运行 install.sh 安装依赖"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
###############################################################################
|
|
# 加载配置
|
|
###############################################################################
|
|
|
|
load_config() {
|
|
log_info "加载配置文件: ${CONFIG_FILE}"
|
|
|
|
if [[ ! -f "${CONFIG_FILE}" ]]; then
|
|
log_error "配置文件不存在: ${CONFIG_FILE}"
|
|
exit 1
|
|
fi
|
|
|
|
OUTPUT_DIR=$(yq eval '.backup.output_dir' "${CONFIG_FILE}")
|
|
BACKUP_PREFIX=$(yq eval '.backup.prefix' "${CONFIG_FILE}")
|
|
RETENTION_ENABLED=$(yq eval '.backup.retention.enabled' "${CONFIG_FILE}")
|
|
KEEP_DAYS=$(yq eval '.backup.retention.keep_days' "${CONFIG_FILE}")
|
|
KEEP_COUNT=$(yq eval '.backup.retention.keep_count' "${CONFIG_FILE}")
|
|
}
|
|
|
|
###############################################################################
|
|
# 清理旧备份(按天数)
|
|
###############################################################################
|
|
|
|
cleanup_by_days() {
|
|
local keep_days=$1
|
|
|
|
log_info "删除 ${keep_days} 天前的备份文件..."
|
|
|
|
local deleted_count=0
|
|
|
|
while IFS= read -r old_file; do
|
|
log_info "删除: ${old_file}"
|
|
rm -f "${old_file}"
|
|
((deleted_count++))
|
|
done < <(find "${OUTPUT_DIR}" -name "${BACKUP_PREFIX}-*.tar.gz" -type f -mtime +${keep_days})
|
|
|
|
log_info "共删除 ${deleted_count} 个旧备份文件"
|
|
}
|
|
|
|
###############################################################################
|
|
# 清理旧备份(按数量)
|
|
###############################################################################
|
|
|
|
cleanup_by_count() {
|
|
local keep_count=$1
|
|
|
|
log_info "保留最近 ${keep_count} 个备份文件..."
|
|
|
|
# 获取所有备份文件,按时间排序
|
|
local all_backups=($(find "${OUTPUT_DIR}" -name "${BACKUP_PREFIX}-*.tar.gz" -type f -printf '%T@ %p\n' | sort -rn | awk '{print $2}'))
|
|
|
|
local total_count=${#all_backups[@]}
|
|
local deleted_count=0
|
|
|
|
if [[ ${total_count} -le ${keep_count} ]]; then
|
|
log_info "当前备份数量 ${total_count} 不超过保留数量 ${keep_count},无需清理"
|
|
return 0
|
|
fi
|
|
|
|
# 删除超出数量的备份
|
|
for ((i=${keep_count}; i<${total_count}; i++)); do
|
|
local old_file="${all_backups[$i]}"
|
|
log_info "删除: ${old_file}"
|
|
rm -f "${old_file}"
|
|
((deleted_count++))
|
|
done
|
|
|
|
log_info "共删除 ${deleted_count} 个旧备份文件"
|
|
}
|
|
|
|
###############################################################################
|
|
# 列出所有备份
|
|
###############################################################################
|
|
|
|
list_backups() {
|
|
log_info "=========================================="
|
|
log_info "备份文件列表"
|
|
log_info "=========================================="
|
|
|
|
if [[ ! -d "${OUTPUT_DIR}" ]]; then
|
|
log_warn "备份目录不存在: ${OUTPUT_DIR}"
|
|
return 0
|
|
fi
|
|
|
|
local backup_files=($(find "${OUTPUT_DIR}" -name "${BACKUP_PREFIX}-*.tar.gz" -type f -printf '%T@ %p %s\n' | sort -rn))
|
|
|
|
if [[ ${#backup_files[@]} -eq 0 ]]; then
|
|
log_info "没有找到备份文件"
|
|
return 0
|
|
fi
|
|
|
|
local count=0
|
|
while IFS=' ' read -r timestamp filepath size; do
|
|
local file_date=$(date -d "@${timestamp}" '+%Y-%m-%d %H:%M:%S' 2>/dev/null || date -r "${timestamp}" '+%Y-%m-%d %H:%M:%S')
|
|
local file_size=$(numfmt --to=iec-i --suffix=B "${size}" 2>/dev/null || echo "${size} bytes")
|
|
((count++))
|
|
printf "%3d. %s %s %s\n" "${count}" "${file_date}" "${file_size}" "$(basename "${filepath}")"
|
|
done < <(find "${OUTPUT_DIR}" -name "${BACKUP_PREFIX}-*.tar.gz" -type f -printf '%T@ %p %s\n' | sort -rn)
|
|
|
|
log_info "=========================================="
|
|
log_info "总计: ${count} 个备份文件"
|
|
}
|
|
|
|
###############################################################################
|
|
# 显示使用帮助
|
|
###############################################################################
|
|
|
|
show_usage() {
|
|
cat << EOF
|
|
Docker Backup 清理工具
|
|
|
|
用法: $0 [选项]
|
|
|
|
选项:
|
|
-h, --help 显示此帮助信息
|
|
-l, --list 列出所有备份文件
|
|
-d, --days DAYS 删除 N 天前的备份文件
|
|
-c, --count COUNT 只保留最近 N 个备份文件
|
|
-a, --auto 使用配置文件中的清理策略自动清理
|
|
|
|
示例:
|
|
$0 --list # 列出所有备份
|
|
$0 --days 7 # 删除 7 天前的备份
|
|
$0 --count 10 # 只保留最近 10 个备份
|
|
$0 --auto # 使用配置文件的策略清理
|
|
|
|
EOF
|
|
}
|
|
|
|
###############################################################################
|
|
# 主函数
|
|
###############################################################################
|
|
|
|
main() {
|
|
# 检查依赖
|
|
check_dependencies
|
|
|
|
# 加载配置
|
|
load_config
|
|
|
|
# 解析参数
|
|
if [[ $# -eq 0 ]]; then
|
|
show_usage
|
|
exit 0
|
|
fi
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case $1 in
|
|
-h|--help)
|
|
show_usage
|
|
exit 0
|
|
;;
|
|
-l|--list)
|
|
list_backups
|
|
exit 0
|
|
;;
|
|
-d|--days)
|
|
if [[ -z "$2" ]] || [[ ! "$2" =~ ^[0-9]+$ ]]; then
|
|
log_error "无效的天数参数: $2"
|
|
exit 1
|
|
fi
|
|
cleanup_by_days "$2"
|
|
exit 0
|
|
;;
|
|
-c|--count)
|
|
if [[ -z "$2" ]] || [[ ! "$2" =~ ^[0-9]+$ ]]; then
|
|
log_error "无效的数量参数: $2"
|
|
exit 1
|
|
fi
|
|
cleanup_by_count "$2"
|
|
exit 0
|
|
;;
|
|
-a|--auto)
|
|
if [[ "${RETENTION_ENABLED}" != "true" ]]; then
|
|
log_warn "配置文件中未启用自动清理"
|
|
exit 0
|
|
fi
|
|
|
|
if [[ "${KEEP_DAYS}" != "null" ]] && [[ "${KEEP_DAYS}" =~ ^[0-9]+$ ]]; then
|
|
cleanup_by_days "${KEEP_DAYS}"
|
|
elif [[ "${KEEP_COUNT}" != "null" ]] && [[ "${KEEP_COUNT}" =~ ^[0-9]+$ ]]; then
|
|
cleanup_by_count "${KEEP_COUNT}"
|
|
else
|
|
log_error "配置文件中未设置有效的清理策略"
|
|
exit 1
|
|
fi
|
|
exit 0
|
|
;;
|
|
*)
|
|
log_error "未知选项: $1"
|
|
show_usage
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
# 执行主函数
|
|
main "$@"
|