# Docker Backup 一个功能强大、易于使用的 Docker 数据备份工具,支持文件夹备份、MySQL 容器数据库备份、定时任务和自动清理旧备份。 ## 功能特性 - ✅ **文件夹备份**: 打包指定文件夹为 tar.gz 压缩文件 - ✅ **排除目录**: 支持配置需要排除的文件夹和文件模式 - ✅ **MySQL 备份**: 备份 MySQL 容器数据库为 sql.gz 压缩文件 - ✅ **合并打包**: 将文件夹和数据库备份合并为单个压缩文件 - ✅ **定时备份**: 使用 systemd timer 实现定时自动备份 - ✅ **自动清理**: 按天数或数量自动清理旧备份文件 - ✅ **灵活配置**: 使用 YAML 配置文件,易于管理 - ✅ **日志记录**: 完整的操作日志,方便问题排查 - ✅ **一键安装**: 提供自动化安装脚本 ## 系统要求 - **操作系统**: Linux (支持 systemd) - **依赖工具**: bash, tar, gzip, docker, yq - **权限**: root 或 sudo 权限 ## 快速开始 ### 1. 一键安装 使用以下命令直接从远程安装: ```bash bash <(curl -sL https://gitea.bcde.io/wangdefa/docker-backup/raw/branch/main/install.sh) ``` 安装脚本会自动完成以下操作: - 检测操作系统 - 安装依赖工具(yq 等) - 从远程仓库下载脚本文件 - 安装到系统目录(`/usr/local/bin`、`/etc/docker-backup`) - 创建配置文件 - 配置 systemd 服务和定时器 - 启动定时任务 ### 2. 编辑配置文件 ```bash sudo vi /etc/docker-backup/config.yml ``` 根据您的实际环境修改配置,主要包括: - 备份输出目录 - 需要备份的文件夹 - 需要排除的目录 - MySQL 容器信息 - 保留策略 ### 3. 测试备份 ```bash # 手动执行一次备份 docker-backup # 查看备份文件 docker-backup-cleanup --list ``` ## 配置说明 ### 配置文件示例 配置文件位于 `/etc/docker-backup/config.yml`,主要配置项说明: ```yaml # 备份基础配置 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" # 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" ``` ## 使用指南 ### 更新工具 ```bash # 更新到最新版本 sudo docker-backup update # 显示帮助信息 docker-backup help ``` 更新功能会: - 自动从远程仓库下载最新版本 - 备份当前版本(以防更新失败) - 同时更新 backup.sh 和 cleanup.sh - 更新失败时自动回滚 ### 定时任务管理 ```bash # 查看定时任务状态 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 ``` ### 手动执行备份 ```bash # 执行备份 docker-backup # 查看备份日志 sudo journalctl -u docker-backup.service -f ``` ### 备份清理策略 工具支持两种清理策略: #### 策略一:按天数清理(keep_days) 保留最近 N 天的备份,删除更早的备份。 ```yaml backup: retention: enabled: true keep_days: 7 # 保留最近 7 天的备份 ``` #### 策略二:按数量清理(keep_count) 保留最近 N 个备份文件,删除多余的旧备份。 ```yaml backup: retention: enabled: true # keep_days: 7 # 注释掉 keep_days keep_count: 10 # 只保留最近 10 个备份 ``` **优先级**:如果同时配置了 `keep_days` 和 `keep_count`,将优先使用 `keep_days` 策略。 ### 备份文件管理 ```bash # 列出所有备份文件 docker-backup-cleanup --list # 删除 7 天前的备份 docker-backup-cleanup --days 7 # 只保留最近 10 个备份 docker-backup-cleanup --count 10 # 使用配置文件中的清理策略 docker-backup-cleanup --auto ``` ## 高级配置 ### 自定义服务名称 ```bash SERVICE_NAME=mybackup bash <(curl -sL https://gitea.bcde.io/wangdefa/docker-backup/raw/branch/main/install.sh) ``` ### 自定义定时计划 ```bash # 每天早上 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 文件: ```bash sudo vi /etc/systemd/system/docker-backup.timer ``` 修改 `OnCalendar` 行,然后重新加载配置: ```bash sudo systemctl daemon-reload sudo systemctl restart docker-backup.timer ``` ## 备份文件格式 备份文件采用时间戳命名格式: ``` backup-20250125-143022.tar.gz ``` 文件内部结构: ``` backup-20250125-143022.tar.gz ├── folders/ │ └── folders.tar.gz # 文件夹备份 └── mysql/ └── mysql.sql.gz # MySQL 数据库备份 ``` ## 备份恢复 ### 1. 解压备份文件 ```bash # 进入备份目录 cd /var/backups/docker-backup # 解压主备份文件 tar -xzf backup-20250125-143022.tar.gz # 查看解压内容 ls -lh # folders/ mysql/ ``` ### 2. 恢复文件夹 ```bash # 解压文件夹备份 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. 恢复 MySQL 数据库 #### 方法一:恢复到 Docker 容器 ```bash # 解压 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 ``` #### 方法二:恢复指定数据库 ```bash # 先解压查看备份内容 gunzip -c mysql.sql.gz | less # 恢复特定数据库 gunzip -c mysql.sql.gz | docker exec -i mysql mysql -uroot -p'your_password' database_name ``` #### 方法三:分步恢复(推荐用于生产环境) ```bash # 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 ``` ### 4. 完整恢复示例 假设需要完整恢复到新服务器: ```bash # 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 ``` ### 5. 恢复注意事项 ⚠️ **重要提示**: 1. **备份当前数据**:恢复前务必备份当前数据 2. **停止应用**:恢复数据库时建议停止应用,避免数据冲突 3. **测试恢复**:在生产环境恢复前,建议先在测试环境验证 4. **权限问题**:恢复文件后检查文件所有者和权限 5. **版本兼容**:确保 MySQL 版本兼容(备份和恢复的版本) 6. **磁盘空间**:确保有足够的磁盘空间进行解压和恢复 ### 6. 验证备份完整性 ```bash # 测试 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 "文件夹备份完整" ``` ## 故障排查 ### 查看服务日志 ```bash # 查看最近的日志 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. 权限不足 确保脚本有执行权限: ```bash 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. 磁盘空间不足 查看磁盘使用情况: ```bash df -h # 手动清理旧备份 docker-backup-cleanup --days 3 ``` #### 4. yq 命令找不到 重新运行安装脚本安装 yq: ```bash bash <(curl -sL https://gitea.bcde.io/wangdefa/docker-backup/raw/branch/main/install.sh) ``` ## 卸载 ```bash 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. **保护配置文件**: 配置文件包含数据库密码,请设置适当的权限: ```bash sudo chmod 600 /etc/docker-backup/config.yml ``` 2. **备份文件权限**: 确保备份文件只能被授权用户访问: ```bash sudo chmod 700 /var/backups/docker-backup ``` 3. **定期测试恢复**: 定期测试备份文件的恢复过程,确保备份有效。 4. **异地备份**: 建议将备份文件同步到远程服务器或云存储。 5. **监控备份**: 配置通知功能,及时了解备份状态。 ## 最佳实践 ### 1. 3-2-1 备份策略 推荐采用 3-2-1 备份策略: - **3** 份数据副本(1 份原始数据 + 2 份备份) - **2** 种不同的存储介质(如本地硬盘 + 云存储) - **1** 份异地备份 ### 2. 定期验证备份 建议每月进行一次完整的恢复测试: ```bash # 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 同步到远程服务器: ```bash # 添加到定时任务或备份后钩子 rsync -avz --delete \ /var/backups/docker-backup/ \ user@remote-server:/backups/ ``` 使用 rclone 同步到云存储: ```bash # 安装 rclone # 配置云存储(如 S3、Google Drive 等) rclone config # 同步备份到云存储 rclone sync /var/backups/docker-backup/ remote:backup/ ``` ## 更新日志 ### 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 ## 相关链接 - **项目主页**: https://gitea.bcde.io/wangdefa/docker-backup - **问题反馈**: https://gitea.bcde.io/wangdefa/docker-backup/issues - **文档**: https://gitea.bcde.io/wangdefa/docker-backup/wiki ## 致谢 感谢所有贡献者的支持和反馈!