set -e
配置
BACKUP_NAME=$(date +"%Y%m%d_%H%M%S")
CONTAINER_NAME="2ace91f4eddd"
BACKUP_SOURCE="/var/opt/gitlab/backups"
BACKUP_DEST="/home/DockerContainer/gitlab/opt/gitlab-backup"
LOG_FILE="/var/log/gitlab-backup.log"
Windows 共享配置
WINDOWS_IP="xxx.xxx.xxx.xxx"
SHARE_NAME="Main"
USERNAME="Administrator"
PASSWORD="xxxxxxxxx"
创建目录
mkdir -p $BACKUP_DEST
echo "=======================================" >> $LOG_FILE
echo "[(date '+%Y-%m-%d %H:%M:%S')\] 开始备份" \>\> LOG_FILE
1. 执行 GitLab 备份
echo "[(date '+%Y-%m-%d %H:%M:%S')\] 创建备份: BACKUP_NAME" >> $LOG_FILE
docker exec -t CONTAINER_NAME gitlab-backup create BACKUP=BACKUP_NAME >> $LOG_FILE 2>&1
2. 备份配置文件
echo "[(date '+%Y-%m-%d %H:%M:%S')\] 备份配置文件" \>\> LOG_FILE
docker cp CONTAINER_NAME:/etc/gitlab/gitlab.rb BACKUP_DEST/gitlab.rb.$BACKUP_NAME
docker cp CONTAINER_NAME:/etc/gitlab/gitlab-secrets.json BACKUP_DEST/gitlab-secrets.json.$BACKUP_NAME
3. 查找并移动备份文件
BACKUP_FILE=(docker exec CONTAINER_NAME ls -t BACKUP_SOURCE \| grep BACKUP_NAME | head -n1)
if [ -n "$BACKUP_FILE" ]; then
echo "[(date '+%Y-%m-%d %H:%M:%S')\] 移动备份文件: BACKUP_FILE" >> $LOG_FILE
docker cp CONTAINER_NAME:BACKUP_SOURCE/BACKUP_FILE BACKUP_DEST/
清理容器内备份文件(可选)
docker exec CONTAINER_NAME rm -f BACKUP_SOURCE/$BACKUP_FILE
else
echo "[(date '+%Y-%m-%d %H:%M:%S')\] 警告:未在容器内找到备份文件,检查宿主机映射目录" \>\> LOG_FILE
如果在宿主机映射目录中查找
if [ -d "/srv/gitlab/backups" ]; then
find /srv/gitlab/backups -name "*BACKUP_NAME\*" -exec mv {} BACKUP_DEST/ \;
fi
fi
4. 上传文件到 Windows 共享并删除本地文件
echo "[(date '+%Y-%m-%d %H:%M:%S')\] 开始上传文件到 Windows 共享" \>\> LOG_FILE
上传并删除函数
upload_and_clean() {
local local_file="$1"
if [ ! -f "$local_file" ]; then
echo "[(date '+%Y-%m-%d %H:%M:%S')\] 文件不存在: local_file" >> $LOG_FILE
return 1
fi
local file_name=(basename "local_file")
echo "[(date '+%Y-%m-%d %H:%M:%S')\] 正在上传: file_name" >> $LOG_FILE
上传到 Windows 共享
if smbclient //{WINDOWS_IP}/{SHARE_NAME} -U {USERNAME}%{PASSWORD} -c "put \"local_file\\" \\"file_name\"" >> $LOG_FILE 2>&1; then
echo "[(date '+%Y-%m-%d %H:%M:%S')\] 上传成功: file_name" >> $LOG_FILE
上传成功后删除本地文件
if rm -f "$local_file"; then
echo "[(date '+%Y-%m-%d %H:%M:%S')\] 已删除本地文件: file_name" >> $LOG_FILE
return 0
else
echo "[(date '+%Y-%m-%d %H:%M:%S')\] 警告:本地文件删除失败: file_name" >> $LOG_FILE
return 1
fi
else
echo "[(date '+%Y-%m-%d %H:%M:%S')\] 上传失败: file_name" >> $LOG_FILE
return 1
fi
}
上传并删除配置文件
if [ -f "BACKUP_DEST/gitlab.rb.BACKUP_NAME" ]; then
upload_and_clean "BACKUP_DEST/gitlab.rb.BACKUP_NAME"
fi
if [ -f "BACKUP_DEST/gitlab-secrets.json.BACKUP_NAME" ]; then
upload_and_clean "BACKUP_DEST/gitlab-secrets.json.BACKUP_NAME"
fi
上传并删除备份文件(如果有)
if [ -n "BACKUP_FILE" \] \&\& \[ -f "BACKUP_DEST/$BACKUP_FILE" ]; then
upload_and_clean "BACKUP_DEST/BACKUP_FILE"
fi
5. 备份完成日志
echo "[(date '+%Y-%m-%d %H:%M:%S')\] 备份上传完成: BACKUP_NAME" >> $LOG_FILE
echo "[(date '+%Y-%m-%d %H:%M:%S')\] 所有操作完成" \>\> LOG_FILE