Gitlab迁移与升级技术方案

一、 文档概述

1.1 编写目的

本文档旨在制定规范、安全的 GitLab 迁移与升级方案,确保代码仓库、CI/CD 流水线等数据无损地从旧服务器迁移至新服务器,并平滑、按序地从 16.11.10-ce.0 升级至目标版本 18.10.1-ce.0

1.2 适用范围

本方案适用于基于 Docker / Docker Compose 部署的社区版的异机迁移与跨大版本升级工作。

二、 现状与目标架构

2.1 源环境(现状)

  • 部署方式:Docker Compose

  • GitLab版本gitlab/gitlab-ce:16.11.10-ce.0

  • 宿主机 数据卷映射

    • 配置目录:/data/gitlab/config (映射至 /etc/gitlab)
    • 数据目录:/data``/gitlab/data (映射至 /var/opt/gitlab)
    • 日志目录:/data/gitlab/logs (映射至 /var/log/gitlab)

2.2 目标环境(期望)

  • 部署方式:Docker Compose
  • GitLab版本gitlab/gitlab-ce:18.10.1-ce.0
  • 宿主机 数据卷映射:与源环境保持一致
  • 服务域名:保持不变

三、 整体迁移与升级策略

可以参考官方的升级工具,来查看升级流程、特性、注意事项。(按需选择是否0停机更新)

"异机同版本迁移 -> 验证切流 -> Docker 镜像阶梯式升级"

由于跨越了 16 -> 17 -> 18 两个大版本,严禁直接修改镜像标签为 18.10.1,否则会导致数据库结构彻底损坏。必须严格遵循官方的必经停靠点进行递进。(详细可以参考官方文档)

四、 迁移前准备工作

4.1 新环境准备

  1. 在新服务器上安装 Docker 与 Docker Compose。

  2. 创建 GitLab 数据挂载目录(保持与旧服务器一致更为方便):

    bash 复制代码
     mkdir -p /data/gitlab/config /data/gitlab/data /data/gitlab/logs
  3. 确保新服务器的磁盘空间充裕。

4.2 梳理升级路径

官方升级路径规则要求必须在特定版本停留以完成数据库后台迁移。从 16.11.10 升级到 18.10.1,预计的停靠节点(请务必在官网升级工具最终核对)为:

16.11.10 -> 17.x.x (17.x必需停靠点) -> 18.x.x (18.x停靠点) -> 18.10.1

4.3 准备 Docker Compose 文件

在新服务器准备 docker-compose.yml,初始版本必须使用旧服务器当前版本

ruby 复制代码
version: '3.8'

services:
  gitlab:
    image: gitlab/gitlab-ce:16.11.10-ce.0  #镜像需要和源gitlab镜像一致
    container_name: gitlab
    restart: always
    ports: #端口以你服务器为准
      - "443:443"
      - "80:80"
      - "22:22"
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /data/gitlab/config:/etc/gitlab
      - /data/gitlab/logs:/var/log/gitlab
      - /data/gitlab/data:/var/opt/gitlab
    shm_size: 256m

#sudo docker exec -it gitlab grep 'Password:' /etc/gitlab/initial_root_password

五、 实施步骤

在迁移和升级前,可以进行一遍演练。由于演练和实际操作一致,就不重复展示过程了。

阶段一:数据备份与迁移(旧服务器操作)

1. 停止用户数据写入(重要)

在旧服务器上,进入容器停止相关服务,防止备份时数据不一致:

bash 复制代码
docker exec -it <旧gitlab容器> gitlab-ctl stop puma
docker exec -it <旧gitlab容器> gitlab-ctl stop sidekiq

# 验证
docker exec -it <旧gitlab容器> gitlab-ctl status

2. 触发全量备份

sql 复制代码
docker exec -t <旧容器名称或ID> gitlab-backup create

备份包会生成在旧服务器的 /data/gitlab/data/backups/ 目录下(例如:1712345678_2026_01_01_16.11.10_gitlab_backup.tar )。

3. 转移备份文件与核心 秘钥

将备份压缩包以及最关键的配置文件打包发送至新服务器:

  • 复制备份文件到新服务器的 /data/gitlab/data/backups/
  • 复制旧服务器上的 /data/gitlab/config/gitlab.rb/data/gitlab/config/gitlab-secrets.json 到新服务器的 /data/gitlab/config/ 目录。(注意: gitlab-secrets.json 如果遗失将导致整个系统双重认证、 CI 变量等无法解密!

(注:Docker 版还有一种快捷迁移法------在彻底停止旧容器后,直接 rsync -avz 整体拷贝 config、data、logs 三个目录到新服务器启动即可。但使用 gitlab-backup 官方标准流程能排查底层文件系统碎片,更为稳妥。本方案采用官方标准恢复流程。)

阶段二:新环境数据恢复(新服务器操作)

1. 启动新环境(空包启动)

在新服务器上执行:

复制代码
docker-compose up -d

等待几分钟,让 GitLab 完成初始化。

2. 准备恢复数据

确保备份文件在新服务器的正确目录下,并赋予权限:

bash 复制代码
chmod 777 /data/gitlab/data/backups/1712345678_2026_01_01_16.11.10_gitlab_backup.tar

进入容器停止数据库相关进程:

sql 复制代码
docker exec -it gitlab gitlab-ctl stop puma
docker exec -it gitlab gitlab-ctl stop sidekiq

docker exec -it gitlab gitlab-ctl start puma
docker exec -it gitlab gitlab-ctl start sidekiq

3. 执行恢复命令

ini 复制代码
docker exec -it gitlab gitlab-backup restore BACKUP=1712345678_2026_01_01_16.11.10
# 交互提示输入两次 yes

4. 恢复完成与 重启

恢复完成后,重启整个容器并检查状态:

bash 复制代码
docker restart gitlab
docker exec -it gitlab gitlab-rake gitlab:check SANITIZE=true

#如果调整了/data/gitlab/config/gitlab.rb 需要重载配置
docker exec -it gitlab gitlab-ctl reconfigure

阶段三:服务切换与验证

  1. 修改 DNS:将域名的解析从旧服务器 IP 切至新服务器 IP。

  2. 在新服务器上进行初步测试:访问页面验证、SSH Pull/Push 测试、检查CI 变量等是否可见。

阶段四:Docker 阶梯式升级 (重点高危操作)

确保 16.11.10 版本在新服务器上运行完美后,开始执行阶梯升级。对于路径上的每一个版本节点(例如从 16.11.10 升至 17.x.x),严格执行以下循环:

Step 1: 修改镜像版本并重建容器

编辑 docker-compose.yml,修改镜像版本号:

arduino 复制代码
    image: 'gitlab/gitlab-ce:17.1.8-ce.0' # 替换为下一个停靠点版本号

执行升级:

复制代码
docker-compose pull
docker-compose up -d

容器启动时,GitLab 会自动执行数据库表结构的 Upgrade 操作,过程可能持续 5-15 分钟。通过 docker logs -f <容器名> 观察进度。

Step 2: 强制等待后台迁移任务(Background Migrations)完毕

这是升级中最关键的一步! 升级完成后,系统后台会在队列中继续迁移大量数据记录。如果后台任务没做完就拉起下一个版本的容器,数据库将发生不可逆损毁

验证后台任务是否完成(在容器运行状态下执行):

bash 复制代码
# 检查普通后台迁移(应返回 0)
docker exec -it gitlab gitlab-rails runner -e production 'puts Gitlab::BackgroundMigration.remaining'

# 检查批处理后台迁移队列(应返回 0)
docker exec -it gitlab gitlab-rails runner -e production 'puts Gitlab::Database::BackgroundMigration::BatchedMigration.queued.count'

也可通过 Web 界面以 管理员 登录:进入 Admin Area -> Monitoring -> Background Migrations 检查状态是否全部为 Finished

Step 3: 重复操作

当上述命令全部返回 0 且系统使用正常后,修改 docker-compose.yml 的 tag 为下一个版本,重复上述操作,直到最终达到 18.10.1-ce.0

六、 验证与验收测试

达到最终版本 18.10.1-ce.0 后,进行全方位验收:

  1. 用户验证:开发人员能否正常通过 Web 登录界面及终端 SSH 连接。

  2. 代码及 Runner 测试:提交一段测试代码,观察 CI/CD 流水线是否正常触发,Docker Runner 是否兼容。

  3. 性能观察:观察宿主机 CPU、内存利用率是否异常。

七、 回滚方案

在异机迁移模式下,回滚基本零成本、零风险。

触发回滚的条件:

  • 中间阶梯升级失败,容器陷入 Restarting 无限循环且无法修复。
  • 升级完成后发现严重的业务阻断级别 Bug。
  • 维护时间窗口耗尽。

实际实施过程中,需要视情况而定

回滚步骤:

  1. 修改 DNS 或负载均衡配置,将域名重新解析回旧服务器 IP

  2. 旧服务器完全处于停止用户写入时的状态,只需恢复服务:

    sql 复制代码
     docker exec -it <旧容器名称> gitlab-ctl start
  3. 业务即可无缝恢复至维护前的 16.11.10 状态,后续排查新机器的升级失败原因。

八、 关键风险与应对策略

风险点 影响面 应对策略
未等待后台任务直接修改 Image Tag 升级 数据库结构不一致,整个系统崩溃,产生 500 报错 Step 4 的 Background Migrations 检查 作为硬性规范,检查返回非 0 绝对不执行下一次 docker-compose up -d
忘记迁移 gitlab-secrets.json 数据库中所有加密字段(如 Runner Token, 用户 2FA, Webhook 密钥)无法读取 在方案执行清单中将此文件单独加粗列出;恢复数据后进行 2FA 登录和 CI 触发测试确认。
Docker 挂载目录权限丢失 容器启动时无权写入 /var/opt/gitlab,一直处于 restarting 状态 使用 chmodupdate-permissions 命令修复;确保宿主机上目录属组与容器内 git 用户映射的 UID/GID 匹配。
升级耗时过长 GitLab 每次大版本变迁自动备份数据库耗时剧增,超出停机窗口 对于 16->18 的多跳升级,如果数据量庞大(如大于 50GB),建议准备一个周末晚上的窗口。
相关推荐
用户223586218202 小时前
核心三角-Command Agent Skill - claude_0x02
前端
张小洛2 小时前
Spring 常用类深度剖析(工具篇 04):CollectionUtils 与 Stream API 的对比与融合
java·后端·spring·spring工具类·spring utils·spring 类解析
竹林8182 小时前
在NFT项目中集成IPFS:从Pinata上传到前端展示的完整踩坑指南
前端·javascript
吴声子夜歌2 小时前
Vue3——渲染函数
前端·vue.js·vue·es6
kunge20132 小时前
UBUNTU Claude Code 报错 claude native binary not installed
后端
Hello--_--World2 小时前
ES15:Object.groupBy() 和 Map.groupBy()、Promise.withResolvers() 相关知识点
开发语言·前端·javascript
暮年2 小时前
Java Map并发-Hashtable
后端
未秃头的程序猿2 小时前
从零到一:深入浅出分布式锁原理与Spring Boot实战(Redis + ZooKeeper)
spring boot·分布式·后端
Soofjan2 小时前
MySQL(3.2):索引应用与优化
后端