#!/bin/bash
# GitLab 配置每日备份脚本 (目录模式)
set -e
CONTAINER_NAME="gitlab"
# 获取日期作为文件夹名称 (格式: 2026-04-20)
DATE=$(date +%Y-%m-%d)
# 基础备份目录
BASE_BACKUP_DIR="/mnt/nas/gitlab_backup/gitlab_22/config_backups"
# 目标备份目录
CURRENT_BACKUP_DIR="$BASE_BACKUP_DIR/$DATE"
LOG_FILE="/var/log/gitlab-config-backup.log"
echo "[$DATE] 开始执行每日配置备份..."
# 1. 检查容器状态
if ! docker ps | grep -q "$CONTAINER_NAME"; then
echo "❌ 错误: GitLab 容器 $CONTAINER_NAME 未运行,无法备份!" | tee -a "$LOG_FILE"
exit 1
fi
# 2. 如果当天的文件夹已存在,则追加时间戳防止冲突
if [ -d "$CURRENT_BACKUP_DIR" ]; then
CURRENT_BACKUP_DIR="${CURRENT_BACKUP_DIR}_$(date +%H%M%S)"
fi
mkdir -p "$CURRENT_BACKUP_DIR"
# 3. 使用临时目录中转
TEMP_DIR=$(mktemp -d)
trap 'rm -rf "$TEMP_DIR"' EXIT
# 4. 提取配置
echo "正在从容器中复制 /etc/gitlab ..."
docker cp "$CONTAINER_NAME:/etc/gitlab" "$TEMP_DIR/config_etc"
# 5. 核心文件校验 (secrets 文件不可为空)
if [ ! -s "$TEMP_DIR/config_etc/gitlab-secrets.json" ]; then
echo "❌ 致命错误: gitlab-secrets.json 校验失败,可能是容器内部路径变更!" | tee -a "$LOG_FILE"
exit 1
fi
# 6. 记录元数据
docker exec "$CONTAINER_NAME" gitlab-ctl version > "$TEMP_DIR/version.txt" 2>/dev/null || true
# 7. 最终同步
cp -a "$TEMP_DIR/." "$CURRENT_BACKUP_DIR/"
# 8. 校验结果
if [ -d "$CURRENT_BACKUP_DIR/config_etc" ]; then
SIZE=$(du -sh "$CURRENT_BACKUP_DIR" | cut -f1)
echo "✅ 备份成功: $CURRENT_BACKUP_DIR (大小: $SIZE)" | tee -a "$LOG_FILE"
else
echo "❌ 错误: 备份目录同步失败!" | tee -a "$LOG_FILE"
exit 1
fi
# 9. 自动删除 30 天前的旧备份
# -maxdepth 1: 只在根目录下找
# -type d: 只找目录
# -mtime +30: 超过 30 天
echo "正在清理 15 天前的旧备份..."
find "$BASE_BACKUP_DIR" -maxdepth 1 -type d -name "20*" -mtime +7 -exec rm -rf {} + 2>/dev/null || true
echo "[$DATE] 备份任务结束。"
数据全量备份
#!/bin/bash
# GitLab 数据全量备份脚本 (Database + Repositories)
set -e
CONTAINER_NAME="gitlab"
DATE=$(date +%Y-%m-%d)
NAS_DATA_DIR="/mnt/nas/gitlab_backup/gitlab_22/data_backups/$DATE"
LOG_FILE="/var/log/gitlab-data-backup.log"
echo "[$DATE] 开始执行 GitLab 官方数据备份..."
mkdir -p "$NAS_DATA_DIR"
# 1. 触发官方备份程序 (包含 DB, Repos, Uploads)
# 注意:这会产生一个巨大的 .tar 文件
docker exec "$CONTAINER_NAME" gitlab-backup create
# 2. 找到刚刚生成的备份文件并移动到 NAS
# 官方备份路径通常对应宿主机的某个目录,或者直接用 docker cp
echo "正在将备份包转移至 NAS..."
# 技巧:获取最新生成的一个 .tar 文件
LATEST_BACKUP=$(docker exec "$CONTAINER_NAME" ls -t /var/opt/gitlab/backups/ | grep .tar | head -n 1)
if [ -n "$LATEST_BACKUP" ]; then
docker cp "$CONTAINER_NAME:/var/opt/gitlab/backups/$LATEST_BACKUP" "$NAS_DATA_DIR/"
# 转移后建议删除容器内的备份文件,节省空间
docker exec "$CONTAINER_NAME" rm "/var/opt/gitlab/backups/$LATEST_BACKUP"
echo "✅ 数据备份成功: $LATEST_BACKUP" | tee -a "$LOG_FILE"
else
echo "❌ 错误: 未能找到生成的备份文件!" | tee -a "$LOG_FILE"
exit 1
fi
# 3. 清理 7 天前的数据备份 (数据包很大,建议保留时间比配置短)
find /mnt/nas/gitlab_backup/gitlab_22/data_backups/ -maxdepth 1 -mtime +7 -exec rm -rf {} + 2>/dev/null || true
如何恢复
既然你已经拥有了配置备份(钥匙)和应用数据备份(内容),恢复流程可以分为四个清晰的步骤。
假设你的新服务器目录结构依然保持一致:
-
配置路径:
/soft/gitlab/config -
数据路径:
/soft/gitlab/data
第 0 步:准备环境(版本对齐)
这是最关键的一步。从你提供的图片看,你的 GitLab 版本是 17.3.3。
在新服务器上启动容器时,镜像标签必须指定为 17.3.3-ce.0。如果版本不一致,数据库迁移会报错,导致恢复失败。
第 1 步:还原配置文件(放置“钥匙”)
在启动 GitLab 之前,先将备份的配置物理放置到宿主机目录。
-
将备份的
gitlab.rb、gitlab-secrets.json以及ssl文件夹(如果有)拷贝到新服务器的/soft/gitlab/config/目录下。 -
特别注意:确保
gitlab-secrets.json权限正确(通常只有 root 可读写)。
第 2 步:启动全新的 GitLab 容器
使用你之前的 Docker 命令启动容器。由于你已经放好了配置文件,GitLab 会按照这些配置运行,但此时里面是空的。
Bash
# 启动命令示例 (确保版本号 17.3.3)
docker run --detach \
--name gitlab \
--restart always \
--volume /soft/gitlab/config:/etc/gitlab \
--volume /soft/gitlab/logs:/var/log/gitlab \
--volume /soft/gitlab/data:/var/opt/gitlab \
gitlab/gitlab-ce:17.3.3-ce.0
第 3 步:还原应用数据(搬入“家具”)
这是处理你图片中那些 db、repositories 数据的阶段。GitLab 官方恢复命令需要一个 .tar 格式的压缩包。
-
准备备份文件:
如果你图片中是一个文件夹,请确保它已被打包成官方格式的
.tar文件(通常备份完就是一个 tar 包)。将该文件拷贝到宿主机的
/soft/gitlab/data/backups/目录下。 -
设置权限:
给备份文件赋予 git 用户权限,否则容器内无法读取:
Bash
chown 998:998 /soft/gitlab/data/backups/1776670786_2026_04_20_17.3.3_gitlab_backup.tar -
执行恢复命令:
进入容器内部执行以下操作:
Bash
# 1. 停止影响数据库的服务 docker exec -it gitlab gitlab-ctl stop puma docker exec -it gitlab gitlab-ctl stop sidekiq # 2. 执行恢复 (注意:BACKUP 参数只需要写文件名的前缀,即时间戳和版本部分) # 例如文件名是 1776670786_2026_04_20_17.3.3_gitlab_backup.tar # 则命令如下: docker exec -it gitlab gitlab-backup restore BACKUP=1776670786_2026_04_20_17.3.3过程中会询问你两次是否确定,输入
yes即可。
第 4 步:重启并校验
恢复完成后,需要重新启动所有服务并检查状态。
-
重启服务:
Bash
docker exec -it gitlab gitlab-ctl reconfigure docker exec -it gitlab gitlab-ctl restart -
检查健康状态:
Bash
docker exec -it gitlab gitlab-rake gitlab:check SANITIZE=true
总结清单:文件到底该放哪?
| 文件类型 | 宿主机存放路径 | 恢复时机 |
|---|---|---|
gitlab.rb |
/soft/gitlab/config/ |
启动容器前 |
gitlab-secrets.json |
/soft/gitlab/config/ |
启动容器前 |
ssl/ 证书文件夹 |
/soft/gitlab/config/ssl/ |
启动容器前 |
*.tar 数据备份包 |
/soft/gitlab/data/backups/ |
启动容器后,执行 restore 命令前 |
💡 给专业程序员的贴士:
如果你发现恢复后页面报错 500,通常是由于 /soft/gitlab/config/gitlab-secrets.json 没有被正确还原,或者里面的密钥与恢复的数据库不匹配。只要确保 Secrets 文件 和 17.3.3 版本 这两点不动摇,恢复成功率就是 100%。

已有 0 条评论