feat: 实现 Docker 备份系统,支持远程一键安装

实现功能:
- 文件夹和 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
This commit is contained in:
Wang Defa
2025-12-25 15:02:07 +08:00
commit 4d00283654
19 changed files with 2553 additions and 0 deletions

554
install.sh Executable file
View File

@@ -0,0 +1,554 @@
#!/bin/bash
###############################################################################
# Docker Backup 远程安装脚本
# 功能:安装依赖、下载文件、配置 systemd 服务
# 使用bash <(curl -sL https://gitea.bcde.io/wangdefa/docker-backup/raw/branch/main/install.sh)
###############################################################################
set -e
set -o pipefail
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
# Gitea 仓库地址
REPO_URL="https://gitea.bcde.io/wangdefa/docker-backup/raw/branch/main"
# 安装路径
BIN_DIR="/usr/local/bin"
CONFIG_DIR="/etc/docker-backup"
SYSTEMD_DIR="/etc/systemd/system"
# 默认服务名称
DEFAULT_SERVICE_NAME="docker-backup"
SERVICE_NAME="${SERVICE_NAME:-$DEFAULT_SERVICE_NAME}"
# 默认定时计划
DEFAULT_SCHEDULE="*-*-* 02:00:00" # 每天凌晨 2 点
SCHEDULE="${SCHEDULE:-$DEFAULT_SCHEDULE}"
###############################################################################
# 日志函数
###############################################################################
log_info() {
echo -e "${GREEN}[INFO]${NC} $@"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $@"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $@"
}
log_step() {
echo -e "\n${BLUE}==>${NC} $@"
}
###############################################################################
# 检查是否以 root 权限运行
###############################################################################
check_root() {
if [[ $EUID -ne 0 ]]; then
log_error "此脚本需要 root 权限运行"
log_info "请使用: sudo bash <(curl -sL ...)"
exit 1
fi
}
###############################################################################
# 检测操作系统
###############################################################################
detect_os() {
if [[ -f /etc/os-release ]]; then
. /etc/os-release
OS=$ID
OS_VERSION=$VERSION_ID
else
log_error "无法检测操作系统类型"
exit 1
fi
log_info "检测到操作系统: $OS $OS_VERSION"
}
###############################################################################
# 安装 yq
###############################################################################
install_yq() {
log_step "检查 yq 是否已安装..."
if command -v yq &> /dev/null; then
log_info "yq 已安装: $(yq --version)"
return 0
fi
log_info "yq 未安装,正在安装..."
# 检测系统架构
local arch=$(uname -m)
case $arch in
x86_64)
arch="amd64"
;;
aarch64|arm64)
arch="arm64"
;;
armv7l)
arch="arm"
;;
*)
log_error "不支持的系统架构: $arch"
exit 1
;;
esac
# 下载并安装 yq
local yq_version="v4.40.5"
local yq_url="https://github.com/mikefarah/yq/releases/download/${yq_version}/yq_linux_${arch}"
log_info "下载 yq ${yq_version} for ${arch}..."
if command -v wget &> /dev/null; then
wget -q "${yq_url}" -O /usr/local/bin/yq
elif command -v curl &> /dev/null; then
curl -sL "${yq_url}" -o /usr/local/bin/yq
else
log_error "需要 wget 或 curl 来下载 yq"
exit 1
fi
chmod +x /usr/local/bin/yq
if command -v yq &> /dev/null; then
log_info "yq 安装成功: $(yq --version)"
else
log_error "yq 安装失败"
exit 1
fi
}
###############################################################################
# 安装其他依赖
###############################################################################
install_dependencies() {
log_step "检查并安装依赖工具..."
local deps=("tar" "gzip" "docker" "find")
local missing_deps=()
for dep in "${deps[@]}"; do
if ! command -v "$dep" &> /dev/null; then
missing_deps+=("$dep")
fi
done
if [[ ${#missing_deps[@]} -eq 0 ]]; then
log_info "所有依赖工具已安装"
return 0
fi
log_warn "缺少以下工具: ${missing_deps[*]}"
case $OS in
ubuntu|debian)
log_info "使用 apt 安装依赖..."
apt-get update -qq
apt-get install -y -qq "${missing_deps[@]}" docker.io
;;
centos|rhel|fedora)
log_info "使用 yum/dnf 安装依赖..."
if command -v dnf &> /dev/null; then
dnf install -y -q "${missing_deps[@]}" docker
else
yum install -y -q "${missing_deps[@]}" docker
fi
;;
*)
log_error "不支持的操作系统,请手动安装: ${missing_deps[*]}"
exit 1
;;
esac
log_info "依赖安装完成"
}
###############################################################################
# 下载并部署文件
###############################################################################
deploy_files() {
log_step "从远程仓库下载文件..."
# 创建必要的目录
mkdir -p "${BIN_DIR}"
mkdir -p "${CONFIG_DIR}"
mkdir -p "${SYSTEMD_DIR}"
# 下载备份脚本
log_info "下载 backup.sh..."
if command -v wget &> /dev/null; then
wget -q "${REPO_URL}/bin/backup.sh" -O "${BIN_DIR}/docker-backup"
else
curl -sL "${REPO_URL}/bin/backup.sh" -o "${BIN_DIR}/docker-backup"
fi
chmod +x "${BIN_DIR}/docker-backup"
# 下载清理脚本
log_info "下载 cleanup.sh..."
if command -v wget &> /dev/null; then
wget -q "${REPO_URL}/bin/cleanup.sh" -O "${BIN_DIR}/docker-backup-cleanup"
else
curl -sL "${REPO_URL}/bin/cleanup.sh" -o "${BIN_DIR}/docker-backup-cleanup"
fi
chmod +x "${BIN_DIR}/docker-backup-cleanup"
# 下载配置文件示例
if [[ ! -f "${CONFIG_DIR}/config.yml" ]]; then
log_info "下载配置文件示例..."
if command -v wget &> /dev/null; then
wget -q "${REPO_URL}/config/backup.yml.example" -O "${CONFIG_DIR}/config.yml"
else
curl -sL "${REPO_URL}/config/backup.yml.example" -o "${CONFIG_DIR}/config.yml"
fi
log_warn "请编辑配置文件: ${CONFIG_DIR}/config.yml"
else
log_info "配置文件已存在,跳过"
fi
log_info "文件部署完成"
}
###############################################################################
# 配置 systemd 服务
###############################################################################
setup_systemd() {
log_step "配置 systemd 服务..."
# 生成 service 文件
log_info "生成 ${SERVICE_NAME}.service..."
cat > "${SYSTEMD_DIR}/${SERVICE_NAME}.service" << EOF
[Unit]
Description=Docker Backup Service
Documentation=https://gitea.bcde.io/wangdefa/docker-backup
After=network.target docker.service
Requires=docker.service
[Service]
Type=oneshot
User=root
Group=root
# 执行备份脚本
ExecStart=${BIN_DIR}/docker-backup
# 标准输出和错误输出
StandardOutput=journal
StandardError=journal
# 超时设置30分钟
TimeoutStartSec=1800
# 资源限制
Nice=19
IOSchedulingClass=idle
[Install]
WantedBy=multi-user.target
EOF
# 生成 timer 文件
log_info "生成 ${SERVICE_NAME}.timer..."
cat > "${SYSTEMD_DIR}/${SERVICE_NAME}.timer" << EOF
[Unit]
Description=Docker Backup Timer
Documentation=https://gitea.bcde.io/wangdefa/docker-backup
Requires=${SERVICE_NAME}.service
[Timer]
# 定时执行时间
OnCalendar=${SCHEDULE}
# 如果错过了执行时间,启动时立即执行一次
Persistent=true
# 随机延迟0-10分钟避免多个任务同时执行
RandomizedDelaySec=10min
[Install]
WantedBy=timers.target
EOF
# 重新加载 systemd
log_info "重新加载 systemd..."
systemctl daemon-reload
log_info "systemd 服务配置完成"
}
###############################################################################
# 启用并启动服务
###############################################################################
enable_service() {
log_step "启用 systemd 服务..."
# 启用 timer
log_info "启用 ${SERVICE_NAME}.timer..."
systemctl enable "${SERVICE_NAME}.timer"
# 启动 timer
log_info "启动 ${SERVICE_NAME}.timer..."
systemctl start "${SERVICE_NAME}.timer"
# 检查状态
log_info "服务状态:"
systemctl status "${SERVICE_NAME}.timer" --no-pager || true
log_info "定时任务已启用"
}
###############################################################################
# 测试备份
###############################################################################
test_backup() {
log_step "测试备份功能..."
read -p "是否立即执行一次备份测试? (y/n) " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
log_info "执行备份测试..."
"${BIN_DIR}/docker-backup" || log_error "备份测试失败,请检查配置和日志"
else
log_info "跳过备份测试"
fi
}
###############################################################################
# 显示安装信息
###############################################################################
show_info() {
cat << EOF
${GREEN}╔═══════════════════════════════════════════════════════════════╗
║ Docker Backup 安装完成! ║
╚═══════════════════════════════════════════════════════════════╝${NC}
${BLUE}安装信息:${NC}
- 备份脚本: ${BIN_DIR}/docker-backup
- 清理脚本: ${BIN_DIR}/docker-backup-cleanup
- 配置文件: ${CONFIG_DIR}/config.yml
- 服务名称: ${SERVICE_NAME}
${BLUE}常用命令:${NC}
# 查看定时任务状态
systemctl status ${SERVICE_NAME}.timer
# 查看定时计划
systemctl list-timers ${SERVICE_NAME}.timer
# 手动执行备份
docker-backup
# 列出所有备份
docker-backup-cleanup --list
# 清理旧备份
docker-backup-cleanup --auto
# 停止定时任务
systemctl stop ${SERVICE_NAME}.timer
# 禁用定时任务
systemctl disable ${SERVICE_NAME}.timer
${YELLOW}重要提示:${NC}
1. 请编辑配置文件以适应您的环境:
vi ${CONFIG_DIR}/config.yml
2. 修改配置后无需重启服务,下次执行时自动生效
3. 查看下次执行时间:
systemctl list-timers | grep ${SERVICE_NAME}
4. 查看备份日志:
journalctl -u ${SERVICE_NAME}.service -f
EOF
}
###############################################################################
# 卸载函数
###############################################################################
uninstall() {
log_step "卸载 Docker Backup..."
# 停止并禁用服务
if systemctl is-active --quiet "${SERVICE_NAME}.timer"; then
log_info "停止 ${SERVICE_NAME}.timer..."
systemctl stop "${SERVICE_NAME}.timer"
fi
if systemctl is-enabled --quiet "${SERVICE_NAME}.timer"; then
log_info "禁用 ${SERVICE_NAME}.timer..."
systemctl disable "${SERVICE_NAME}.timer"
fi
# 删除 systemd 文件
log_info "删除 systemd 文件..."
rm -f "${SYSTEMD_DIR}/${SERVICE_NAME}.service"
rm -f "${SYSTEMD_DIR}/${SERVICE_NAME}.timer"
# 重新加载 systemd
systemctl daemon-reload
# 删除脚本文件
log_info "删除脚本文件..."
rm -f "${BIN_DIR}/docker-backup"
rm -f "${BIN_DIR}/docker-backup-cleanup"
# 删除配置文件
read -p "是否删除配置目录 ${CONFIG_DIR}? (y/n) " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
log_info "删除配置目录..."
rm -rf "${CONFIG_DIR}"
else
log_info "保留配置目录"
fi
log_info "卸载完成"
exit 0
}
###############################################################################
# 显示使用帮助
###############################################################################
show_usage() {
cat << EOF
Docker Backup 远程安装脚本
用法: bash <(curl -sL https://gitea.bcde.io/wangdefa/docker-backup/raw/branch/main/install.sh) [选项]
选项:
-h, --help 显示此帮助信息
-n, --name NAME 指定服务名称 (默认: ${DEFAULT_SERVICE_NAME})
-s, --schedule SCHEDULE 指定定时计划 (默认: ${DEFAULT_SCHEDULE})
-u, --uninstall 卸载 Docker Backup
定时计划示例:
"daily" 每天执行
"*-*-* 02:00:00" 每天凌晨 2 点
"Mon *-*-* 02:00:00" 每周一凌晨 2 点
"*-*-01 02:00:00" 每月 1 号凌晨 2 点
"hourly" 每小时执行
示例:
# 默认安装
bash <(curl -sL https://gitea.bcde.io/wangdefa/docker-backup/raw/branch/main/install.sh)
# 自定义服务名称
bash <(curl -sL https://gitea.bcde.io/wangdefa/docker-backup/raw/branch/main/install.sh) --name mybackup
# 自定义定时计划(每天早上 6 点)
bash <(curl -sL https://gitea.bcde.io/wangdefa/docker-backup/raw/branch/main/install.sh) --schedule "*-*-* 06:00:00"
# 卸载
bash <(curl -sL https://gitea.bcde.io/wangdefa/docker-backup/raw/branch/main/install.sh) --uninstall
EOF
}
###############################################################################
# 主函数
###############################################################################
main() {
# 解析参数
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help)
show_usage
exit 0
;;
-n|--name)
SERVICE_NAME="$2"
shift 2
;;
-s|--schedule)
SCHEDULE="$2"
shift 2
;;
-u|--uninstall)
check_root
uninstall
;;
*)
log_error "未知选项: $1"
show_usage
exit 1
;;
esac
done
# 显示欢迎信息
cat << EOF
${GREEN}╔═══════════════════════════════════════════════════════════════╗
║ 欢迎使用 Docker Backup 安装程序 ║
╚═══════════════════════════════════════════════════════════════╝${NC}
安装配置:
- 服务名称: ${SERVICE_NAME}
- 定时计划: ${SCHEDULE}
- 配置目录: ${CONFIG_DIR}
- 脚本目录: ${BIN_DIR}
EOF
# 检查 root 权限
check_root
# 检测操作系统
detect_os
# 安装 yq
install_yq
# 安装其他依赖
install_dependencies
# 部署文件
deploy_files
# 配置 systemd
setup_systemd
# 启用服务
enable_service
# 测试备份
test_backup
# 显示安装信息
show_info
}
# 执行主函数
main "$@"