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 # 数据库备份
This commit is contained in:
56
README.md
56
README.md
@@ -5,6 +5,7 @@
|
|||||||
## 功能特性
|
## 功能特性
|
||||||
|
|
||||||
- ✅ **文件夹备份**: 打包指定文件夹为 tar.gz 压缩文件
|
- ✅ **文件夹备份**: 打包指定文件夹为 tar.gz 压缩文件
|
||||||
|
- ✅ **单文件备份**: 支持备份多个单独的配置文件(如 .env、config.yml 等)
|
||||||
- ✅ **排除目录**: 支持配置需要排除的文件夹和文件模式
|
- ✅ **排除目录**: 支持配置需要排除的文件夹和文件模式
|
||||||
- ✅ **MySQL 备份**: 备份 MySQL 容器数据库为 sql.gz 压缩文件
|
- ✅ **MySQL 备份**: 备份 MySQL 容器数据库为 sql.gz 压缩文件
|
||||||
- ✅ **合并打包**: 将文件夹和数据库备份合并为单个压缩文件
|
- ✅ **合并打包**: 将文件夹和数据库备份合并为单个压缩文件
|
||||||
@@ -89,6 +90,14 @@ folders:
|
|||||||
- "*/temp"
|
- "*/temp"
|
||||||
- "*/cache"
|
- "*/cache"
|
||||||
|
|
||||||
|
# 单文件备份配置
|
||||||
|
files:
|
||||||
|
enabled: true # 是否启用单文件备份
|
||||||
|
sources: # 需要备份的文件列表
|
||||||
|
- "/etc/docker-backup/config.yml"
|
||||||
|
- "/etc/nginx/nginx.conf"
|
||||||
|
- "/opt/app/.env"
|
||||||
|
|
||||||
# MySQL 数据库备份配置
|
# MySQL 数据库备份配置
|
||||||
mysql:
|
mysql:
|
||||||
enabled: true # 是否启用 MySQL 备份
|
enabled: true # 是否启用 MySQL 备份
|
||||||
@@ -252,6 +261,8 @@ backup-20250125-143022.tar.gz
|
|||||||
backup-20250125-143022.tar.gz
|
backup-20250125-143022.tar.gz
|
||||||
├── folders/
|
├── folders/
|
||||||
│ └── folders.tar.gz # 文件夹备份
|
│ └── folders.tar.gz # 文件夹备份
|
||||||
|
├── files/
|
||||||
|
│ └── files.tar.gz # 单文件备份
|
||||||
└── mysql/
|
└── mysql/
|
||||||
└── mysql.sql.gz # MySQL 数据库备份
|
└── mysql.sql.gz # MySQL 数据库备份
|
||||||
```
|
```
|
||||||
@@ -292,7 +303,33 @@ cp -r opt/gitea /tmp/restore/
|
|||||||
# 检查无误后再复制到目标位置
|
# 检查无误后再复制到目标位置
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3. 恢复 MySQL 数据库
|
### 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 容器
|
#### 方法一:恢复到 Docker 容器
|
||||||
|
|
||||||
@@ -354,7 +391,7 @@ docker exec mysql mysql -uroot -p'your_password' -e "SHOW DATABASES;"
|
|||||||
rm /tmp/restore_mysql.sql
|
rm /tmp/restore_mysql.sql
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4. 完整恢复示例
|
### 5. 完整恢复示例
|
||||||
|
|
||||||
假设需要完整恢复到新服务器:
|
假设需要完整恢复到新服务器:
|
||||||
|
|
||||||
@@ -389,7 +426,7 @@ ls -lh /opt/gitea/
|
|||||||
docker-compose up -d
|
docker-compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
### 5. 恢复注意事项
|
### 6. 恢复注意事项
|
||||||
|
|
||||||
⚠️ **重要提示**:
|
⚠️ **重要提示**:
|
||||||
|
|
||||||
@@ -400,7 +437,7 @@ docker-compose up -d
|
|||||||
5. **版本兼容**:确保 MySQL 版本兼容(备份和恢复的版本)
|
5. **版本兼容**:确保 MySQL 版本兼容(备份和恢复的版本)
|
||||||
6. **磁盘空间**:确保有足够的磁盘空间进行解压和恢复
|
6. **磁盘空间**:确保有足够的磁盘空间进行解压和恢复
|
||||||
|
|
||||||
### 6. 验证备份完整性
|
### 7. 验证备份完整性
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 测试 tar.gz 文件完整性
|
# 测试 tar.gz 文件完整性
|
||||||
@@ -416,6 +453,11 @@ echo "SQL 备份文件完整"
|
|||||||
cd ../folders
|
cd ../folders
|
||||||
tar -tzf folders.tar.gz > /dev/null
|
tar -tzf folders.tar.gz > /dev/null
|
||||||
echo "文件夹备份完整"
|
echo "文件夹备份完整"
|
||||||
|
|
||||||
|
# 测试单文件备份完整性
|
||||||
|
cd ../files
|
||||||
|
tar -tzf files.tar.gz > /dev/null
|
||||||
|
echo "单文件备份完整"
|
||||||
```
|
```
|
||||||
|
|
||||||
## 故障排查
|
## 故障排查
|
||||||
@@ -577,6 +619,12 @@ rclone sync /var/backups/docker-backup/ remote:backup/
|
|||||||
|
|
||||||
## 更新日志
|
## 更新日志
|
||||||
|
|
||||||
|
### v1.3.0 (2025-12-26)
|
||||||
|
|
||||||
|
- ✨ 新增:支持单个文件备份功能(files 配置)
|
||||||
|
- 📝 文档:添加单文件备份和恢复的详细说明
|
||||||
|
- 🔧 优化:备份文件结构更清晰,支持文件夹、单文件、数据库分类备份
|
||||||
|
|
||||||
### v1.2.0 (2025-12-25)
|
### v1.2.0 (2025-12-25)
|
||||||
|
|
||||||
- ✨ 新增:支持 `keep_count` 按数量保留备份策略
|
- ✨ 新增:支持 `keep_count` 按数量保留备份策略
|
||||||
|
|||||||
@@ -151,6 +151,9 @@ load_config() {
|
|||||||
# 读取文件夹备份配置
|
# 读取文件夹备份配置
|
||||||
FOLDERS_ENABLED=$(yq eval '.folders.enabled' "${CONFIG_FILE}")
|
FOLDERS_ENABLED=$(yq eval '.folders.enabled' "${CONFIG_FILE}")
|
||||||
|
|
||||||
|
# 读取单文件备份配置
|
||||||
|
FILES_ENABLED=$(yq eval '.files.enabled' "${CONFIG_FILE}")
|
||||||
|
|
||||||
# 读取 MySQL 配置
|
# 读取 MySQL 配置
|
||||||
MYSQL_ENABLED=$(yq eval '.mysql.enabled' "${CONFIG_FILE}")
|
MYSQL_ENABLED=$(yq eval '.mysql.enabled' "${CONFIG_FILE}")
|
||||||
MYSQL_CONTAINER=$(yq eval '.mysql.container_name' "${CONFIG_FILE}")
|
MYSQL_CONTAINER=$(yq eval '.mysql.container_name' "${CONFIG_FILE}")
|
||||||
@@ -256,6 +259,68 @@ backup_folders() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# 备份单个文件
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
backup_files() {
|
||||||
|
if [[ "${FILES_ENABLED}" != "true" ]]; then
|
||||||
|
log_info "单文件备份未启用,跳过"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
log_info "开始备份单个文件..."
|
||||||
|
|
||||||
|
# 创建临时目录
|
||||||
|
local temp_backup_dir="${TEMP_DIR}/files"
|
||||||
|
mkdir -p "${temp_backup_dir}"
|
||||||
|
|
||||||
|
# 获取要备份的文件数量
|
||||||
|
local source_count=$(yq eval '.files.sources | length' "${CONFIG_FILE}")
|
||||||
|
|
||||||
|
if [[ "${source_count}" == "0" ]] || [[ "${source_count}" == "null" ]]; then
|
||||||
|
log_warn "未配置要备份的文件"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 收集要备份的文件
|
||||||
|
local files_tar="${temp_backup_dir}/files.tar.gz"
|
||||||
|
local tar_sources=""
|
||||||
|
local valid_files=0
|
||||||
|
|
||||||
|
for i in $(seq 0 $((source_count - 1))); do
|
||||||
|
local source_file=$(yq eval ".files.sources[$i]" "${CONFIG_FILE}")
|
||||||
|
|
||||||
|
if [[ ! -f "${source_file}" ]]; then
|
||||||
|
log_warn "源文件不存在,跳过: ${source_file}"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
tar_sources+=" ${source_file}"
|
||||||
|
valid_files=$((valid_files + 1))
|
||||||
|
log_info "添加备份文件: ${source_file}"
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ ${valid_files} -eq 0 ]]; then
|
||||||
|
log_warn "没有有效的备份文件"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 执行打包
|
||||||
|
log_info "开始打包文件..."
|
||||||
|
# 将 tar 的 stdout 和 stderr 都重定向到 stderr,避免干扰函数返回值
|
||||||
|
eval "tar -czf '${files_tar}' ${tar_sources}" >&2 2>&1
|
||||||
|
|
||||||
|
if [[ -f "${files_tar}" ]]; then
|
||||||
|
local tar_size=$(du -h "${files_tar}" | cut -f1)
|
||||||
|
log_info "文件备份完成: ${files_tar} (大小: ${tar_size})"
|
||||||
|
echo "${files_tar}"
|
||||||
|
else
|
||||||
|
log_error "文件备份失败"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# 备份 MySQL 数据库
|
# 备份 MySQL 数据库
|
||||||
###############################################################################
|
###############################################################################
|
||||||
@@ -331,7 +396,8 @@ backup_mysql() {
|
|||||||
|
|
||||||
merge_backups() {
|
merge_backups() {
|
||||||
local folders_tar=$1
|
local folders_tar=$1
|
||||||
local mysql_dump=$2
|
local files_tar=$2
|
||||||
|
local mysql_dump=$3
|
||||||
|
|
||||||
log_info "开始合并备份文件..."
|
log_info "开始合并备份文件..."
|
||||||
|
|
||||||
@@ -346,6 +412,10 @@ merge_backups() {
|
|||||||
files_to_pack+=" ${folders_tar}"
|
files_to_pack+=" ${folders_tar}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [[ -n "${files_tar}" ]] && [[ -f "${files_tar}" ]]; then
|
||||||
|
files_to_pack+=" ${files_tar}"
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ -n "${mysql_dump}" ]] && [[ -f "${mysql_dump}" ]]; then
|
if [[ -n "${mysql_dump}" ]] && [[ -f "${mysql_dump}" ]]; then
|
||||||
files_to_pack+=" ${mysql_dump}"
|
files_to_pack+=" ${mysql_dump}"
|
||||||
fi
|
fi
|
||||||
@@ -362,6 +432,10 @@ merge_backups() {
|
|||||||
files_list+=" ${folders_tar#${TEMP_DIR}/}"
|
files_list+=" ${folders_tar#${TEMP_DIR}/}"
|
||||||
log_info "添加到合并: ${folders_tar#${TEMP_DIR}/} ($(du -h "${folders_tar}" | cut -f1))"
|
log_info "添加到合并: ${folders_tar#${TEMP_DIR}/} ($(du -h "${folders_tar}" | cut -f1))"
|
||||||
fi
|
fi
|
||||||
|
if [[ -n "${files_tar}" ]] && [[ -f "${files_tar}" ]]; then
|
||||||
|
files_list+=" ${files_tar#${TEMP_DIR}/}"
|
||||||
|
log_info "添加到合并: ${files_tar#${TEMP_DIR}/} ($(du -h "${files_tar}" | cut -f1))"
|
||||||
|
fi
|
||||||
if [[ -n "${mysql_dump}" ]] && [[ -f "${mysql_dump}" ]]; then
|
if [[ -n "${mysql_dump}" ]] && [[ -f "${mysql_dump}" ]]; then
|
||||||
files_list+=" ${mysql_dump#${TEMP_DIR}/}"
|
files_list+=" ${mysql_dump#${TEMP_DIR}/}"
|
||||||
log_info "添加到合并: ${mysql_dump#${TEMP_DIR}/} ($(du -h "${mysql_dump}" | cut -f1))"
|
log_info "添加到合并: ${mysql_dump#${TEMP_DIR}/} ($(du -h "${mysql_dump}" | cut -f1))"
|
||||||
@@ -586,11 +660,14 @@ run_backup() {
|
|||||||
# 备份文件夹
|
# 备份文件夹
|
||||||
local folders_tar=$(backup_folders)
|
local folders_tar=$(backup_folders)
|
||||||
|
|
||||||
|
# 备份单个文件
|
||||||
|
local files_tar=$(backup_files)
|
||||||
|
|
||||||
# 备份 MySQL
|
# 备份 MySQL
|
||||||
local mysql_dump=$(backup_mysql)
|
local mysql_dump=$(backup_mysql)
|
||||||
|
|
||||||
# 合并备份
|
# 合并备份
|
||||||
local final_backup=$(merge_backups "${folders_tar}" "${mysql_dump}")
|
local final_backup=$(merge_backups "${folders_tar}" "${files_tar}" "${mysql_dump}")
|
||||||
|
|
||||||
# 清理旧备份
|
# 清理旧备份
|
||||||
cleanup_old_backups
|
cleanup_old_backups
|
||||||
|
|||||||
@@ -36,6 +36,17 @@ folders:
|
|||||||
- "*/.git"
|
- "*/.git"
|
||||||
- "*/node_modules"
|
- "*/node_modules"
|
||||||
|
|
||||||
|
# 单文件备份配置
|
||||||
|
files:
|
||||||
|
# 是否启用单文件备份
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
# 需要备份的文件列表(支持多个)
|
||||||
|
sources:
|
||||||
|
- "/etc/docker-backup/config.yml"
|
||||||
|
- "/etc/nginx/nginx.conf"
|
||||||
|
- "/opt/app/.env"
|
||||||
|
|
||||||
# MySQL 数据库备份配置
|
# MySQL 数据库备份配置
|
||||||
mysql:
|
mysql:
|
||||||
# 是否启用 MySQL 备份
|
# 是否启用 MySQL 备份
|
||||||
|
|||||||
Reference in New Issue
Block a user