一、 文档概述
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 新环境准备
-
在新服务器上安装 Docker 与 Docker Compose。
-
创建 GitLab 数据挂载目录(保持与旧服务器一致更为方便):
bashmkdir -p /data/gitlab/config /data/gitlab/data /data/gitlab/logs -
确保新服务器的磁盘空间充裕。
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
阶段三:服务切换与验证
-
修改 DNS:将域名的解析从旧服务器 IP 切至新服务器 IP。
-
在新服务器上进行初步测试:访问页面验证、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 后,进行全方位验收:
-
用户验证:开发人员能否正常通过 Web 登录界面及终端 SSH 连接。
-
代码及 Runner 测试:提交一段测试代码,观察 CI/CD 流水线是否正常触发,Docker Runner 是否兼容。
-
性能观察:观察宿主机 CPU、内存利用率是否异常。
七、 回滚方案
在异机迁移模式下,回滚基本零成本、零风险。
触发回滚的条件:
- 中间阶梯升级失败,容器陷入
Restarting无限循环且无法修复。 - 升级完成后发现严重的业务阻断级别 Bug。
- 维护时间窗口耗尽。
实际实施过程中,需要视情况而定
回滚步骤:
-
修改 DNS 或负载均衡配置,将域名重新解析回旧服务器 IP。
-
旧服务器完全处于停止用户写入时的状态,只需恢复服务:
sqldocker exec -it <旧容器名称> gitlab-ctl start -
业务即可无缝恢复至维护前的 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 状态 |
使用 chmod 或 update-permissions 命令修复;确保宿主机上目录属组与容器内 git 用户映射的 UID/GID 匹配。 |
| 升级耗时过长 | GitLab 每次大版本变迁自动备份数据库耗时剧增,超出停机窗口 | 对于 16->18 的多跳升级,如果数据量庞大(如大于 50GB),建议准备一个周末晚上的窗口。 |