Wang Defa a00314964d feat(backup): 添加单文件备份功能
- 添加 files 配置节,支持备份多个单独文件
- 实现 backup_files() 函数,处理单文件备份逻辑
- 更新 merge_backups() 函数,支持合并 files 备份
- 更新配置文件示例,添加 files 配置说明
- 更新 README 文档:
  - 添加单文件备份功能说明
  - 添加 files 配置示例
  - 添加单文件恢复详细步骤
  - 更新备份文件结构说明
  - 添加单文件完整性验证方法
  - 添加 v1.3.0 更新日志

使用场景:
- 备份配置文件(如 /etc/nginx/nginx.conf)
- 备份环境变量文件(如 /opt/app/.env)
- 备份其他重要的单个文件

备份结构:
backup.tar.gz
├── folders/folders.tar.gz  # 文件夹备份
├── files/files.tar.gz      # 单文件备份
└── mysql/mysql.sql.gz      # 数据库备份
2025-12-26 13:06:33 +08:00

Docker Backup

一个功能强大、易于使用的 Docker 数据备份工具支持文件夹备份、MySQL 容器数据库备份、定时任务和自动清理旧备份。

功能特性

  • 文件夹备份: 打包指定文件夹为 tar.gz 压缩文件
  • 单文件备份: 支持备份多个单独的配置文件(如 .env、config.yml 等)
  • 排除目录: 支持配置需要排除的文件夹和文件模式
  • MySQL 备份: 备份 MySQL 容器数据库为 sql.gz 压缩文件
  • 合并打包: 将文件夹和数据库备份合并为单个压缩文件
  • 定时备份: 使用 systemd timer 实现定时自动备份
  • 自动清理: 按天数或数量自动清理旧备份文件
  • 灵活配置: 使用 YAML 配置文件,易于管理
  • 日志记录: 完整的操作日志,方便问题排查
  • 一键安装: 提供自动化安装脚本

系统要求

  • 操作系统: Linux (支持 systemd)
  • 依赖工具: bash, tar, gzip, docker, yq
  • 权限: root 或 sudo 权限

快速开始

1. 一键安装

使用以下命令直接从远程安装:

bash <(curl -sL https://gitea.bcde.io/wangdefa/docker-backup/raw/branch/main/install.sh)

安装脚本会自动完成以下操作:

  • 检测操作系统
  • 安装依赖工具yq 等)
  • 从远程仓库下载脚本文件
  • 安装到系统目录(/usr/local/bin/etc/docker-backup
  • 创建配置文件
  • 配置 systemd 服务和定时器
  • 启动定时任务

2. 编辑配置文件

sudo vi /etc/docker-backup/config.yml

根据您的实际环境修改配置,主要包括:

  • 备份输出目录
  • 需要备份的文件夹
  • 需要排除的目录
  • MySQL 容器信息
  • 保留策略

3. 测试备份

# 手动执行一次备份
docker-backup

# 查看备份文件
docker-backup-cleanup --list

配置说明

配置文件示例

配置文件位于 /etc/docker-backup/config.yml,主要配置项说明:

# 备份基础配置
backup:
  output_dir: "/var/backups/docker-backup"  # 备份文件存放目录
  prefix: "backup"                          # 备份文件名前缀
  retention:
    enabled: true                           # 是否启用自动清理
    keep_days: 7                            # 保留最近 N 天的备份
    # keep_count: 10                        # 或保留最近 N 个备份(与 keep_days 二选一)

# 文件夹备份配置
folders:
  enabled: true                             # 是否启用文件夹备份
  sources:                                  # 需要备份的文件夹列表
    - "/var/lib/docker/volumes"
    - "/opt/app/data"
  excludes:                                 # 需要排除的目录模式
    - "*/logs"
    - "*/temp"
    - "*/cache"

# 单文件备份配置
files:
  enabled: true                             # 是否启用单文件备份
  sources:                                  # 需要备份的文件列表
    - "/etc/docker-backup/config.yml"
    - "/etc/nginx/nginx.conf"
    - "/opt/app/.env"

# MySQL 数据库备份配置
mysql:
  enabled: true                             # 是否启用 MySQL 备份
  container_name: "mysql"                   # MySQL 容器名称
  username: "root"                          # 数据库用户名
  password: "your_password_here"            # 数据库密码
  databases:                                # 要备份的数据库列表
    - "database1"
    - "database2"
  # 或者备份所有数据库: databases: "all"

# 日志配置
logging:
  enabled: true
  log_file: "/var/log/docker-backup.log"
  level: "INFO"

使用指南

更新工具

# 更新到最新版本
sudo docker-backup update

# 显示帮助信息
docker-backup help

更新功能会:

  • 自动从远程仓库下载最新版本
  • 备份当前版本(以防更新失败)
  • 同时更新 backup.sh 和 cleanup.sh
  • 更新失败时自动回滚

定时任务管理

# 查看定时任务状态
systemctl status docker-backup.timer

# 查看下次执行时间
systemctl list-timers docker-backup.timer

# 停止定时任务
sudo systemctl stop docker-backup.timer

# 启动定时任务
sudo systemctl start docker-backup.timer

# 禁用定时任务(开机不自动启动)
sudo systemctl disable docker-backup.timer

# 启用定时任务(开机自动启动)
sudo systemctl enable docker-backup.timer

手动执行备份

# 执行备份
docker-backup

# 查看备份日志
sudo journalctl -u docker-backup.service -f

备份清理策略

工具支持两种清理策略:

策略一按天数清理keep_days

保留最近 N 天的备份,删除更早的备份。

backup:
  retention:
    enabled: true
    keep_days: 7      # 保留最近 7 天的备份

策略二按数量清理keep_count

保留最近 N 个备份文件,删除多余的旧备份。

backup:
  retention:
    enabled: true
    # keep_days: 7    # 注释掉 keep_days
    keep_count: 10    # 只保留最近 10 个备份

优先级:如果同时配置了 keep_dayskeep_count,将优先使用 keep_days 策略。

备份文件管理

# 列出所有备份文件
docker-backup-cleanup --list

# 删除 7 天前的备份
docker-backup-cleanup --days 7

# 只保留最近 10 个备份
docker-backup-cleanup --count 10

# 使用配置文件中的清理策略
docker-backup-cleanup --auto

高级配置

自定义服务名称

SERVICE_NAME=mybackup bash <(curl -sL https://gitea.bcde.io/wangdefa/docker-backup/raw/branch/main/install.sh)

自定义定时计划

# 每天早上 6 点执行
SCHEDULE="*-*-* 06:00:00" bash <(curl -sL https://gitea.bcde.io/wangdefa/docker-backup/raw/branch/main/install.sh)

# 每周一凌晨 2 点执行
SCHEDULE="Mon *-*-* 02:00:00" bash <(curl -sL https://gitea.bcde.io/wangdefa/docker-backup/raw/branch/main/install.sh)

# 每小时执行
SCHEDULE="hourly" bash <(curl -sL https://gitea.bcde.io/wangdefa/docker-backup/raw/branch/main/install.sh)

修改已安装的定时计划

编辑 timer 文件:

sudo vi /etc/systemd/system/docker-backup.timer

修改 OnCalendar 行,然后重新加载配置:

sudo systemctl daemon-reload
sudo systemctl restart docker-backup.timer

备份文件格式

备份文件采用时间戳命名格式:

backup-20250125-143022.tar.gz

文件内部结构:

backup-20250125-143022.tar.gz
├── folders/
│   └── folders.tar.gz    # 文件夹备份
├── files/
│   └── files.tar.gz      # 单文件备份
└── mysql/
    └── mysql.sql.gz      # MySQL 数据库备份

备份恢复

1. 解压备份文件

# 进入备份目录
cd /var/backups/docker-backup

# 解压主备份文件
tar -xzf backup-20250125-143022.tar.gz

# 查看解压内容
ls -lh
# folders/  mysql/

2. 恢复文件夹

# 解压文件夹备份
cd folders
tar -xzf folders.tar.gz

# 查看解压的文件
ls -lh
# 将显示备份时的完整路径opt/gitea/

# 方法一:直接恢复到原位置(会覆盖现有文件)
sudo cp -r opt/gitea/* /opt/gitea/

# 方法二:恢复到临时目录检查
mkdir -p /tmp/restore
cp -r opt/gitea /tmp/restore/
# 检查无误后再复制到目标位置

3. 恢复单个文件

# 解压单文件备份
cd ../files
tar -xzf files.tar.gz

# 查看解压的文件
ls -lh
# 将显示备份时的完整路径etc/docker-backup/config.yml

# 方法一:直接恢复到原位置(会覆盖现有文件)
sudo cp etc/docker-backup/config.yml /etc/docker-backup/
sudo cp etc/nginx/nginx.conf /etc/nginx/
sudo cp opt/app/.env /opt/app/

# 方法二:选择性恢复
# 只恢复需要的文件
sudo cp etc/nginx/nginx.conf /etc/nginx/

# 方法三:恢复到临时目录检查
mkdir -p /tmp/restore-files
cp -r etc /tmp/restore-files/
# 检查无误后再复制到目标位置

4. 恢复 MySQL 数据库

方法一:恢复到 Docker 容器

# 解压 SQL 文件
cd ../mysql
gunzip -c mysql.sql.gz > mysql.sql

# 恢复到 MySQL 容器
docker exec -i mysql mysql -uroot -p'your_password' < mysql.sql

# 或者恢复单个数据库
docker exec -i mysql mysql -uroot -p'your_password' database_name < mysql.sql

# 清理临时文件
rm mysql.sql

方法二:恢复指定数据库

# 先解压查看备份内容
gunzip -c mysql.sql.gz | less

# 恢复特定数据库
gunzip -c mysql.sql.gz | docker exec -i mysql mysql -uroot -p'your_password' database_name

方法三:分步恢复(推荐用于生产环境)

# 1. 先测试 SQL 文件是否完整
gunzip -t mysql.sql.gz
echo "测试通过: SQL 文件完整"

# 2. 解压到临时位置
gunzip -c mysql.sql.gz > /tmp/restore_mysql.sql

# 3. 检查 SQL 文件内容
head -n 50 /tmp/restore_mysql.sql
tail -n 50 /tmp/restore_mysql.sql

# 4. 停止应用(避免数据写入)
# docker-compose down  # 根据实际情况

# 5. 备份当前数据库(以防恢复失败)
docker exec mysql mysqldump -uroot -p'your_password' --all-databases | gzip > /tmp/current_backup.sql.gz

# 6. 执行恢复
docker exec -i mysql mysql -uroot -p'your_password' < /tmp/restore_mysql.sql

# 7. 验证恢复结果
docker exec mysql mysql -uroot -p'your_password' -e "SHOW DATABASES;"

# 8. 重启应用
# docker-compose up -d  # 根据实际情况

# 9. 清理临时文件
rm /tmp/restore_mysql.sql

5. 完整恢复示例

假设需要完整恢复到新服务器:

# 1. 复制备份文件到新服务器
scp backup-20250125-143022.tar.gz root@new-server:/tmp/

# 2. 在新服务器上解压
cd /tmp
tar -xzf backup-20250125-143022.tar.gz

# 3. 恢复文件夹
cd folders
tar -xzf folders.tar.gz
sudo cp -r opt/gitea /opt/

# 4. 启动 MySQL 容器(如果还没启动)
docker-compose up -d mysql

# 5. 等待 MySQL 启动完成
sleep 10

# 6. 恢复数据库
cd ../mysql
gunzip -c mysql.sql.gz | docker exec -i mysql mysql -uroot -p'your_password'

# 7. 验证恢复
docker exec mysql mysql -uroot -p'your_password' -e "SHOW DATABASES;"
ls -lh /opt/gitea/

# 8. 启动所有服务
docker-compose up -d

6. 恢复注意事项

⚠️ 重要提示

  1. 备份当前数据:恢复前务必备份当前数据
  2. 停止应用:恢复数据库时建议停止应用,避免数据冲突
  3. 测试恢复:在生产环境恢复前,建议先在测试环境验证
  4. 权限问题:恢复文件后检查文件所有者和权限
  5. 版本兼容:确保 MySQL 版本兼容(备份和恢复的版本)
  6. 磁盘空间:确保有足够的磁盘空间进行解压和恢复

7. 验证备份完整性

# 测试 tar.gz 文件完整性
tar -tzf backup-20250125-143022.tar.gz > /dev/null
echo "主备份文件完整"

# 测试 SQL 压缩文件完整性
cd mysql
gunzip -t mysql.sql.gz
echo "SQL 备份文件完整"

# 测试文件夹备份完整性
cd ../folders
tar -tzf folders.tar.gz > /dev/null
echo "文件夹备份完整"

# 测试单文件备份完整性
cd ../files
tar -tzf files.tar.gz > /dev/null
echo "单文件备份完整"

故障排查

查看服务日志

# 查看最近的日志
sudo journalctl -u docker-backup.service -n 50

# 实时跟踪日志
sudo journalctl -u docker-backup.service -f

# 查看特定时间的日志
sudo journalctl -u docker-backup.service --since "2025-01-25 14:00:00"

常见问题

1. 权限不足

确保脚本有执行权限:

sudo chmod +x /usr/local/bin/docker-backup
sudo chmod +x /usr/local/bin/docker-backup-cleanup

2. MySQL 连接失败

检查:

  • MySQL 容器是否运行:docker ps | grep mysql
  • 用户名和密码是否正确
  • 容器名称是否匹配

3. 磁盘空间不足

查看磁盘使用情况:

df -h

# 手动清理旧备份
docker-backup-cleanup --days 3

4. yq 命令找不到

重新运行安装脚本安装 yq

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) --uninstall

卸载脚本会:

  • 停止并禁用 systemd 服务
  • 删除 systemd 服务文件
  • 删除脚本文件
  • 可选删除配置目录(会提示确认)

项目结构

docker-backup/
├── bin/
│   ├── backup.sh                          # 主备份脚本
│   └── cleanup.sh                         # 清理脚本
├── config/
│   └── backup.yml.example                 # 配置文件示例
├── systemd/
│   ├── docker-backup.service.template     # systemd service 模板
│   └── docker-backup.timer.template       # systemd timer 模板
├── install.sh                             # 安装脚本
└── README.md                              # 项目文档

安全建议

  1. 保护配置文件: 配置文件包含数据库密码,请设置适当的权限:

    sudo chmod 600 /etc/docker-backup/config.yml
    
  2. 备份文件权限: 确保备份文件只能被授权用户访问:

    sudo chmod 700 /var/backups/docker-backup
    
  3. 定期测试恢复: 定期测试备份文件的恢复过程,确保备份有效。

  4. 异地备份: 建议将备份文件同步到远程服务器或云存储。

  5. 监控备份: 配置通知功能,及时了解备份状态。

最佳实践

1. 3-2-1 备份策略

推荐采用 3-2-1 备份策略:

  • 3 份数据副本1 份原始数据 + 2 份备份)
  • 2 种不同的存储介质(如本地硬盘 + 云存储)
  • 1 份异地备份

2. 定期验证备份

建议每月进行一次完整的恢复测试:

# 1. 创建测试环境
mkdir -p /tmp/backup-test

# 2. 解压最新备份
cd /tmp/backup-test
tar -xzf /var/backups/docker-backup/backup-latest.tar.gz

# 3. 验证文件完整性
cd folders && tar -tzf folders.tar.gz
cd ../mysql && gunzip -t mysql.sql.gz

# 4. 测试数据库恢复(可选)
# 在测试容器中恢复并验证

3. 备份前的准备

  • 确保有足够的磁盘空间(至少是数据大小的 2 倍)
  • 在数据库负载较低时执行备份
  • 记录备份配置变更历史

4. 异地备份示例

使用 rsync 同步到远程服务器:

# 添加到定时任务或备份后钩子
rsync -avz --delete \
  /var/backups/docker-backup/ \
  user@remote-server:/backups/

使用 rclone 同步到云存储:

# 安装 rclone
# 配置云存储(如 S3、Google Drive 等)
rclone config

# 同步备份到云存储
rclone sync /var/backups/docker-backup/ remote:backup/

更新日志

v1.3.0 (2025-12-26)

  • 新增支持单个文件备份功能files 配置)
  • 📝 文档:添加单文件备份和恢复的详细说明
  • 🔧 优化:备份文件结构更清晰,支持文件夹、单文件、数据库分类备份

v1.2.0 (2025-12-25)

  • 新增:支持 keep_count 按数量保留备份策略
  • 新增:docker-backup update 自动更新功能
  • 新增:docker-backup help 帮助命令
  • 🐛 修复:清理策略未正确执行的问题
  • 📝 文档:添加详细的备份恢复指南

v1.1.0 (2025-01-25)

  • 📝 文档:完善使用说明和故障排查
  • 🔧 优化:改进日志输出格式

v1.0.0 (2025-01-25)

  • 🎉 初始版本发布
  • 支持文件夹备份
  • 支持 MySQL 容器备份
  • 支持定时任务
  • 支持自动清理旧备份
  • 提供一键安装脚本

贡献

欢迎提交 Issue 和 Pull Request

贡献指南

  1. Fork 本仓库
  2. 创建特性分支 (git checkout -b feature/amazing-feature)
  3. 提交更改 (git commit -m 'feat: 添加某个功能')
  4. 推送到分支 (git push origin feature/amazing-feature)
  5. 提交 Pull Request

请遵循项目的代码规范和提交信息格式(参考 Conventional Commits

许可证

MIT License

作者

wangdefa

相关链接

致谢

感谢所有贡献者的支持和反馈!

Description
No description provided
Readme 89 KiB
Languages
Shell 100%