Files
docker-backup/README.md
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

680 lines
16 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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
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"
# 单文件备份配置
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"
```
## 使用指南
### 更新工具
```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 # 文件夹备份
├── files/
│ └── files.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. 恢复单个文件
```bash
# 解压单文件备份
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 容器
```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
```
### 5. 完整恢复示例
假设需要完整恢复到新服务器:
```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
```
### 6. 恢复注意事项
⚠️ **重要提示**
1. **备份当前数据**:恢复前务必备份当前数据
2. **停止应用**:恢复数据库时建议停止应用,避免数据冲突
3. **测试恢复**:在生产环境恢复前,建议先在测试环境验证
4. **权限问题**:恢复文件后检查文件所有者和权限
5. **版本兼容**:确保 MySQL 版本兼容(备份和恢复的版本)
6. **磁盘空间**:确保有足够的磁盘空间进行解压和恢复
### 7. 验证备份完整性
```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 "文件夹备份完整"
# 测试单文件备份完整性
cd ../files
tar -tzf files.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.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
## 相关链接
- **项目主页**: https://gitea.bcde.io/wangdefa/docker-backup
- **问题反馈**: https://gitea.bcde.io/wangdefa/docker-backup/issues
- **文档**: https://gitea.bcde.io/wangdefa/docker-backup/wiki
## 致谢
感谢所有贡献者的支持和反馈!