Ubuntu 上 GitLab 项目迁移实操指南
迁移方式总览与选择
- 方式一:项目导出/导入(Project Export/Import)
适合跨实例迁移少量项目,能携带大部分项目元数据(如 Issues、MR、Wiki、LFS 等),但存在版本兼容限制与速率限制;从 GitLab 13.0 起,通常只能导入比当前实例小两个小版本的包;不包含 CI/CD 变量、Webhooks、Runner 注册令牌、容器镜像 等敏感或实例级对象。适合“少量项目、要保留元数据”的场景。
- 方式二:整实例备份与恢复(Backup & Restore)
适合把旧服务器“整套”迁到新服务器(含 数据库、附件、仓库、CI 日志/产物、LFS、Pages、Registry、Terraform States、Snippets、Group wikis 等),要求两端 GitLab 版本与类型(CE/EE)完全一致;恢复时会清空目标实例现有数据。适合“整站搬家/同版本替换”。
- 方式三:命令行镜像迁移(git clone --mirror / git push --mirror)
最稳妥可控,保留 所有 refs(分支、标签、notes 等),不依赖实例功能,适合“超大仓库、批量迁移、需要可重复流程”的场景;仅迁移代码与 Git 历史,不携带 Issue/MR/CI 等元数据。
方式一 项目导出与导入(适合少量项目、保留元数据)
- 在原实例导出
进入项目 → Settings → General → Advanced → Export project,生成后下载归档(.tar.gz)。注意:导出包不含 CI/CD 变量、Webhooks、Runner 令牌、容器镜像 等。
- 在新实例导入
新建项目 → Import project → GitLab export → 上传归档并创建。若导入缓慢或失败,检查实例的导入速率限制与归档大小。
- 版本兼容要点
从 13.0 起支持跨实例导入,但一般仅支持导入比当前实例小两个小版本的导出包;跨大版本或跨类型(CE ↔ EE)不建议使用此法。
方式二 整实例备份与恢复(适合整站迁移、同版本)
- 版本与准备
两端安装 相同版本与类型(CE/EE) 的 GitLab。查看版本:
cat /opt/gitlab/embedded/service/gitlab-rails/VERSION
备份任务不会包含敏感配置文件,需手动备份并迁移:
/etc/gitlab/gitlab.rb、/etc/gitlab/gitlab-secrets.json(Omnibus 包)。
- 在旧实例创建备份
Omnibus(GitLab 12.2+)
sudo gitlab-backup create
或旧版 Rake
sudo gitlab-rake gitlab:backup:create
备份默认位于 /var/opt/gitlab/backups/,文件名类似:1658368484_2022_07_21_14.8.2_gitlab_backup.tar。
- 将备份与配置拷贝到新实例
scp 旧机:/var/opt/gitlab/backups/*.tar 新机:/var/opt/gitlab/backups/
sudo cp 旧机:/etc/gitlab/gitlab.rb /etc/gitlab/gitlab.rb
sudo cp 旧机:/etc/gitlab/gitlab-secrets.json /etc/gitlab/gitlab-secrets.json
- 在新实例恢复
建议先停写
sudo gitlab-ctl stop unicorn
sudo gitlab-ctl stop sidekiq
恢复(BACKUP= 只填时间戳,不含 “_gitlab_backup.tar”)
sudo gitlab-rake gitlab:backup:restore BACKUP=1658368484_2022_07_21_14.8.2
启动
sudo gitlab-ctl start
如曾自定义备份路径,确保新实例配置一致并 reconfigure
sudo gitlab-ctl reconfigure
- 重要提示
恢复会清空目标实例现有数据;若 /etc/gitlab/gitlab-secrets.json 未正确恢复,可能出现 2FA/Runner 无法使用或 402 错误;PostgreSQL 扩展相关的告警(如 pg_trgm/btree_gist)在 Omnibus 恢复中可安全忽略。
方式三 命令行镜像迁移(最稳妥、可控,适合大仓库/批量)
- 单仓库迁移
1) 裸克隆镜像
git clone --mirror https://git.source.com/group/repo.git
cd repo.git
2) 推送到新 GitLab(先在 GitLab 创建空项目获取目标 URL)
git push --mirror https://gitlab.example.com/group/repo.git
- 批量迁移脚本(repos.txt:每行“源URL 目标URL”)
while read -r src dst; do
name=$(basename “$src” .git)
rm -rf “$name”.git
git clone --mirror “$src” “$name”.git
git -C “$name”.git remote set-url --push origin “$dst”
git -C “$name”.git push --mirror
done < repos.txt
- 适用与局限
保留 所有 Git 对象与 refs,流程可重复、对大仓库更稳;但不迁移 Issue/MR/CI/CD/权限 等元数据,需要另行处理或改用“项目导出/导入”。
迁移后验证与常见问题
- 快速验证
登录新实例检查:项目 代码、分支/标签、Issues/MR/Wiki(若使用导出导入)、LFS 是否完整;本地更新远程地址测试 git pull/push;CI 运行器在新实例重新注册并更新 Runner 令牌。
- 常见问题与处理
- 页面 500 或 Runner/CI 异常:多因 gitlab-secrets.json 不一致,恢复该文件并重启;必要时在控制台清理相关加密令牌(谨慎操作)。
- 导入/恢复很慢或超时:项目导出导入有 速率限制;超大仓库优先用 git --mirror。
- 整实例恢复报错(如扩展权限):Omnibus 环境中可忽略部分 PostgreSQL 扩展 告警。
- 仅迁移代码不迁元数据:使用 git clone --mirror / git push --mirror 即可。