实现功能: - 文件夹和 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
555 lines
15 KiB
Bash
Executable File
555 lines
15 KiB
Bash
Executable File
#!/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 "$@"
|