GitLab 迁移

一、迁移前准备

1.版本一致性要求(关键)

⚠️新旧服务器 GitLab 版本必须完全一致(包括小版本号),否则备份无法恢复。

复制代码
bash# 查询当前 GitLab 版本
cat /opt/gitlab/embedded/service/gitlab-rails/VERSION
# 或
gitlab-rake gitlab:env:info | grep "GitLab information"

2.迁移方式选择

|----------------|----------|---------|--------|
| 方式 | 适用场景 | 优点 | 缺点 |
| 官方备份恢复(推荐) | 常规迁移 | 简单、官方支持 | 需版本一致 |
| rsync全量迁移 | 升级同步迁移 | 快速 | 需停机 |
| Docker卷迁移 | Docker部署 | 直接复制数据卷 | 需停容器 |
| 数据库+仓库分离 | 大型实例 | 灵活 | 操作复杂 |


二、官方备份恢复方式(推荐)

【旧服务器】第一步:备份配置文件(必做,备份不含配置)

复制代码
bash# 备份密钥文件(secrets:存储加密密钥)
cp /etc/gitlab/gitlab-secrets.json /backup/gitlab-secrets.json

# 备份主配置文件
cp /etc/gitlab/gitlab.rb /backup/gitlab.rb

# 备份 SSL 证书(如有)
cp -r /etc/gitlab/ssl /backup/ssl

# 打包整个 /etc/gitlab 目录(最稳妥)
tar -czvf /backup/gitlab-etc-$(date +%F).tar.gz /etc/gitlab

【旧服务器】第二步:停止写入服务,保证数据一致

复制代码
bash# 停止 Puma/Unicorn 和 Sidekiq(其他服务保留,备份需要)
gitlab-ctl stop puma
gitlab-ctl stop sidekiq

# 确认状态
gitlab-ctl status

【旧服务器】第三步:执行备份

复制代码
bash# 执行备份命令(较慢,取决于仓库大小)
gitlab-backup create
# 老版本命令:gitlab-rake gitlab:backup:create

# 可选参数:跳过部分内容减小备份体积
gitlab-backup create SKIP=artifacts,uploads STRATEGY=copy

# 备份默认存放位置
ls -lh /var/opt/gitlab/backups/
# 生成文件名示例:1715592345_2026_05_13_16.11.5_gitlab_backup.tar

【旧服务器】第四步:传输到新服务器

复制代码
bash# 方式一:scp
scp /var/opt/gitlab/backups/1715592345_2026_05_13_16.11.5_gitlab_backup.tar \
    root@newserver:/var/opt/gitlab/backups/

# 方式二:rsync(推荐,支持断点续传)
rsync -avP --progress \
    /var/opt/gitlab/backups/*.tar \
    /backup/gitlab-etc-*.tar.gz \
    /backup/gitlab-secrets.json \
    root@newserver:/tmp/gitlab-migrate/

【新服务器】第五步:安装相同版本的 GitLab

复制代码
bash# CentOS/RHEL ------ 指定版本安装
yum install -y gitlab-ce-16.11.5-ce.0.el7

# Ubuntu/Debian ------ 指定版本安装
apt-get install -y gitlab-ce=16.11.5-ce.0

# Docker 方式 ------ 指定镜像 tag
docker pull gitlab/gitlab-ce:16.11.5-ce.0

【新服务器】第六步:恢复配置文件

复制代码
bash# 恢复 secrets 和 gitlab.rb(务必在 reconfigure 前)
cp /tmp/gitlab-migrate/gitlab-secrets.json /etc/gitlab/gitlab-secrets.json
cp /tmp/gitlab-migrate/gitlab.rb /etc/gitlab/gitlab.rb

# 如需修改域名 IP
vi /etc/gitlab/gitlab.rb
# 修改:external_url 'http://newserver.example.com'

# 应用配置
gitlab-ctl reconfigure
gitlab-ctl restart

【新服务器】第七步:恢复数据

复制代码
bash# 放置备份文件到备份目录
mv /tmp/gitlab-migrate/*_gitlab_backup.tar /var/opt/gitlab/backups/

# 修改备份文件权限(必须 git 用户可读写)
chown git:git /var/opt/gitlab/backups/*_gitlab_backup.tar
chmod 600 /var/opt/gitlab/backups/*_gitlab_backup.tar

# 停止写入服务
gitlab-ctl stop puma
gitlab-ctl stop sidekiq
gitlab-ctl status

# 执行恢复(BACKUP 参数只传时间戳部分,不含 _gitlab_backup.tar)
gitlab-backup restore BACKUP=1715592345_2026_05_13_16.11.5

# 过程中会两次询问是否覆盖,输入 yes 确认

【新服务器】第八步:重启并验证

复制代码
bash# 重新配置并启动
gitlab-ctl reconfigure
gitlab-ctl restart

# 健康检查
gitlab-rake gitlab:check SANITIZE=true
gitlab-rake gitlab:doctor:secrets

# 查看服务状态
gitlab-ctl status

三、Docker部署GitLab 迁移方式

1. 旧容器数据导出

复制代码
bash# 查看当前容器挂载路径
docker inspect gitlab | grep -A 5 Mounts

# 标准挂载目录(官方镜像默认)
# /etc/gitlab     -> 配置
# /var/log/gitlab -> 日志
# /var/opt/gitlab -> 数据

# 停容器(避免数据写入)
docker stop gitlab

# 打包数据
tar -czvf /backup/gitlab-config.tar.gz /srv/gitlab/config
tar -czvf /backup/gitlab-data.tar.gz   /srv/gitlab/data
tar -czvf /backup/gitlab-logs.tar.gz   /srv/gitlab/logs

2.传输到新服务器

复制代码
bashrsync -avP /backup/gitlab-*.tar.gz root@newserver:/tmp/

3.新服务器解压并启动

复制代码
bash# 解压
mkdir -p /srv/gitlab
cd /srv/gitlab
tar -xzvf /tmp/gitlab-config.tar.gz -C /
tar -xzvf /tmp/gitlab-data.tar.gz   -C /
tar -xzvf /tmp/gitlab-logs.tar.gz   -C /

# docker-compose.yaml 示例
cat > docker-compose.yaml <<'EOF'
version: '3.8'
services:
  gitlab:
    image: gitlab/gitlab-ce:16.11.5-ce.0    # 版本必须和旧环境一致
    container_name: gitlab
    restart: always
    hostname: 'gitlab.example.com'
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        external_url 'http://gitlab.example.com'
        gitlab_rails['time_zone'] = 'Asia/Shanghai'
    ports:
      - "80:80"
      - "443:443"
      - "22:22"
    volumes:
      - /srv/gitlab/config:/etc/gitlab
      - /srv/gitlab/logs:/var/log/gitlab
      - /srv/gitlab/data:/var/opt/gitlab
    shm_size: '256m'
EOF

docker-compose up -d

# 观察启动日志
docker logs -f gitlab

四、rsync 全量迁移方式(同版本快速迁移)

复制代码
bash# 【旧服务器】停止 GitLab
gitlab-ctl stop

# 【新服务器】安装相同版本 GitLab 但不启动
yum install -y gitlab-ce-16.11.5-ce.0.el7
# 初次配置完成后立即停止
gitlab-ctl stop

# 【旧服务器】全量同步数据
rsync -avP --delete /etc/gitlab/       root@newserver:/etc/gitlab/
rsync -avP --delete /var/opt/gitlab/   root@newserver:/var/opt/gitlab/
rsync -avP --delete /var/log/gitlab/   root@newserver:/var/log/gitlab/

# 【新服务器】重新配置并启动
gitlab-ctl reconfigure
gitlab-ctl start
gitlab-ctl status

五、迁移后必做校验项

复制代码
bash# 1. 健康检查
gitlab-rake gitlab:check SANITIZE=true

# 2. 密钥完整性(最重要!)
gitlab-rake gitlab:doctor:secrets
# 若报错 "Failed to decrypt",说明 gitlab-secrets.json 未正确迁移

# 3. 仓库完整性检查
gitlab-rake gitlab:git:fsck

# 4. 后台任务状态
gitlab-rake gitlab:sidekiq:check

# 5. 检查 Git LFS、CI Runner 可用性
gitlab-rake gitlab:lfs:check

Web层面验证清单

  • 管理员能正常登录 /admin
  • 项目列表、仓库代码可访问
  • Issues、MR、Wiki 正常
  • CI/CD Pipeline 历史正常
  • Runner 重新注册或修改地址
  • Webhook 目标地址是否需更新
  • SSH Key git clone git@newserver:xx/xx.git 能拉取代码
  • 邮件 SMTP 通知能送达

六、客户端切换与收尾

1.修改客户端 Git仓库远程地址

复制代码
bash# 方式一:修改 remote url
git remote set-url origin git@newserver:group/project.git

# 方式二:DNS 平滑切换(推荐)
# 保持域名不变,仅修改 DNS 解析到新服务器 IP,客户端无感知

2.SSH known_hosts 清理

复制代码
bash# 客户端删除旧 HostKey 避免告警
ssh-keygen -R oldserver
ssh-keygen -R newserver   # 强制重新信任

3.旧服务器处理

复制代码
bash# 观察 1-2 周无异常后,保留最后一次备份再下线
gitlab-ctl stop
# 最后一份冷备份
tar -czvf /backup/gitlab-final-$(date +%F).tar.gz /etc/gitlab /var/opt/gitlab

七、迁移流程图

复制代码
graph TD
    A["开始迁移"] --> B["确认新旧版本一致"]
    B --> C["旧服务器:停止 puma+sidekiq"]
    C --> D["旧服务器:gitlab-backup create"]
    D --> E["旧服务器:备份 /etc/gitlab 和 gitlab-secrets.json"]
    E --> F["传输备份文件到新服务器 (rsync/scp)"]
    F --> G["新服务器:安装相同版本 GitLab"]
    G --> H["新服务器:恢复 gitlab.rb 和 secrets.json"]
    H --> I["新服务器:gitlab-ctl reconfigure"]
    I --> J["新服务器:gitlab-backup restore"]
    J --> K["新服务器:reconfigure + restart"]
    K --> L["执行 gitlab-rake check 检查"]
    L --> M{"校验通过?"}
    M -->|否| N["排查 secrets / 权限 / 版本"]
    N --> J
    M -->|是| O["DNS/客户端切换"]
    O --> P["观察1-2周"]
    P --> Q["旧服务器冷备份后下线"]

八、常见坑与解决方案

|------------------------|--------------------------|---------------------------------------------|
| 问题 | 原因 | 解决方案 |
| Failed to decrypt | gitlab-secrets.json未迁移 | 从旧机复制该文件后reconfigure |
| backup restore报版本不匹配 | GitLab 版本不一致 | 新机安装完全相同版本 |
| 恢复后CI Runner离线 | Runner Token加密失效 | Admin→Runners 重新注册 |
| 仓库 500 错误 | 文件权限 git:git丢失 | chown -R git:git /var/opt/gitlab/git-data |
| 2FA全部失效 | secrets 未迁移 | 同上,必须迁移 secrets.json |
| 备份文件过大 | artifacts/uploads体积大 | 备份时SKIP=artifacts,单独rsync |
| 邮件无法发送 | SMTP 地址/网络变化 | 修改gitlab.rb中smtp 配置 |
| Docker 容器启不来 | shm_size不足 | 增加shm_size: '256m' |


九、最佳实践建议

  1. 先做演练:在测试环境完整走一遍流程,估算停机时间。
  2. 最小停机窗口:选择业务低峰期(凌晨),停机一般 1--4 小时。
  3. 双跑过渡:旧服务器保留只读访问 1 周,新服务器提供写入。
  4. 备份 3-2-1 原则:3 份副本、2 种介质、1 份异地。
  5. 版本升级单独做:迁移 + 升级分两步,先迁移同版本再按官方路径升级。
  6. GitLab 升级路径 :跨大版本必须遵循官方升级路径
  7. 自动化脚本:将 backup → rsync → restore 写成脚本,可复用。
相关推荐
xurime13 小时前
Excelize 开源十周年,发布 2.11.0 版本
golang·开源·github·excel·导出·导入·excelize·基础库
逛逛GitHub19 小时前
自测会不会被 Claude Code 标记为中国用户,有人做了个网页。
github
逛逛GitHub19 小时前
终于有个非 AI 相关的项目登上 GitHub 热榜,高低得推荐一下。
github
Lion0920 小时前
【04】50 行代码实现最小 Agent:不依赖任何框架
人工智能·github
狂炫冰美式1 天前
凌晨睡不着,我给台风巴威写了个追踪网站
前端·后端·github
Maynor9961 天前
GitHub 外链 / 自荐入口清单
github
oscar9991 天前
3.4 Nginx 负载均衡——动态再平衡的反人性纪律
nginx·github·负载均衡·财富源代码
杨超越luckly1 天前
Agent 应用指南:基于 OurAirports 的中国机场设施数据可视化
python·html·github·可视化·机场设施
Maynor在掘金1 天前
憋了两个月,Gemini 3.5 Pro 终于要来了!前端代码一次生成,传闻 7 月 17 日亮相。
github