如何高效将GitLab Docker Registry迁移至Nexus3私有镜像仓库
我之前帮团队处理过类似的跨GitLab实例+镜像仓库迁移需求,手动一个个拉取推送确实效率低到爆炸,分享几个亲测好用的自动化方案给你:
1. Shell脚本批量迁移(通用易上手)
这个方案适合镜像数量中等、需要自定义迁移逻辑的场景,核心是通过API获取镜像列表,再循环处理每个镜像的拉取、重命名和推送:
首先确保你能登录两个镜像仓库:
# 登录GitLab Registry docker login gitlab.example.com:5050 -u <你的GitLab用户名> -p <GitLab个人访问令牌> # 登录Nexus3 Docker仓库 docker login nexus.example.com:8082 -u <Nexus用户名> -p <Nexus密码>
然后编写批量处理脚本(需要提前安装jq来解析JSON响应):
#!/bin/bash # 替换为你的GitLab Registry地址 GITLAB_REGISTRY="gitlab.example.com:5050" # 替换为你的Nexus3 Docker仓库地址(比如hosted类型仓库的地址) NEXUS_REGISTRY="nexus.example.com:8082/docker-hosted" # GitLab认证信息 GITLAB_USER="<你的GitLab用户名>" GITLAB_TOKEN="<GitLab个人访问令牌>" # 获取GitLab Registry中所有镜像仓库名 REPOS=$(curl -s -u "$GITLAB_USER:$GITLAB_TOKEN" https://$GITLAB_REGISTRY/v2/_catalog | jq -r '.repositories[]') for REPO in $REPOS; do echo "开始处理镜像仓库: $REPO" # 获取该仓库下的所有标签 TAGS=$(curl -s -u "$GITLAB_USER:$GITLAB_TOKEN" https://$GITLAB_REGISTRY/v2/$REPO/tags/list | jq -r '.tags[]') for TAG in $TAGS; do echo "迁移镜像: $GITLAB_REGISTRY/$REPO:$TAG -> $NEXUS_REGISTRY/$REPO:$TAG" # 拉取GitLab镜像 docker pull "$GITLAB_REGISTRY/$REPO:$TAG" # 重命名镜像适配Nexus地址 docker tag "$GITLAB_REGISTRY/$REPO:$TAG" "$NEXUS_REGISTRY/$REPO:$TAG" # 推送到Nexus3 docker push "$NEXUS_REGISTRY/$REPO:$TAG" # 可选:删除本地镜像释放空间 docker rmi "$GITLAB_REGISTRY/$REPO:$TAG" "$NEXUS_REGISTRY/$REPO:$TAG" done done
2. 使用Skopeo工具(轻量无Docker Daemon依赖)
如果你的服务器不想运行Docker Daemon,或者需要更高效的镜像迁移(无需本地存储),skopeo是绝佳选择——它可以直接在两个镜像仓库之间复制镜像,速度更快、资源占用更低:
先安装Skopeo(以Debian/Ubuntu为例):
apt update && apt install skopeo -y
单个镜像复制命令:
skopeo copy \ --src-creds <GitLab用户名>:<GitLab令牌> docker://gitlab.example.com:5050/my/project/image:v1 \ --dest-creds <Nexus用户名>:<Nexus密码> docker://nexus.example.com:8082/docker-hosted/my/project/image:v1
批量复制的话,同样可以结合脚本逻辑,用Skopeo替换Docker命令,省去本地拉取和存储的步骤,非常适合大规模镜像迁移。
3. 结合GitLab API精准迁移项目关联镜像
如果你的镜像和GitLab项目强绑定,可以通过GitLab API获取项目对应的镜像仓库,实现精准迁移,避免处理无关镜像:
首先获取所有GitLab项目的ID:
curl -s -H "PRIVATE-TOKEN: <GitLab管理员令牌>" https://gitlab.example.com/api/v4/projects?per_page=100 | jq -r '.[] | .id, .path_with_namespace'
然后针对单个项目,获取它的容器镜像仓库:
curl -s -H "PRIVATE-TOKEN: <GitLab管理员令牌>" https://gitlab.example.com/api/v4/projects/<项目ID>/registry/repositories
拿到镜像仓库列表后,再用上面的脚本或者Skopeo进行批量迁移即可。
迁移GitLab CE到GitLab.com时,推荐用官方的项目导出/导入功能:在GitLab CE的项目设置里导出项目(包含仓库代码、Issues、Wiki、流水线等数据),然后在GitLab.com创建新项目时选择导入该导出包。不过要注意:GitLab的项目导出包不包含容器镜像,所以镜像还是需要用上面的方法单独迁移。
注意事项:
- 迁移前务必备份GitLab Registry和Nexus3的镜像数据,避免迁移过程中数据丢失
- 如果镜像体积较大,建议在网络带宽充足的机器上执行迁移,或者分批次处理
- 迁移完成后,记得验证Nexus3中的镜像能否正常拉取和运行
内容的提问来源于stack exchange,提问作者Badr




