gitlab-ee 13.6.7 迁移并使用 docker compose 部署
前言
旧的服务器要到期了,需要把上面的服务迁移到新服务器。最最重要的就是这个 gitlab 服务,里面存放的是之前几个项目的源码。虽然感觉没什么用,也不太重要,但也算是自己编程生涯的重要见证。
之前给公司的 gitlab 做过一次迁移:gitlab 迁移 - 备份还原,当时主要还是通过搜索引擎去找的方案,也确实可用。整体上看,一共是一个备份文件加上两个配置文件,gitlab 的迁移过程还是相对比较简单的。
在接触了 docker 容器化部署之后,就想着把所有的项目和相关联的服务都通过 docker 容器去部署。这样管理清晰明了,到了后面学习了 K8s 之后,可以针对一些项目进行全流程的管理,比如 Java 项目的编译、打包、自动部署等。
计划的流程是,先准备好 gitlab 需要的备份文件,之后搭建 docker compose 项目,并拉取相同版本的镜像,最后在启动成功后,使用已有的 https-portal 做反向代理,将请求转发到 gitlab 服务容器。
准备工作
主要的备份文件:
/etc/gitlab/gitlab.rb/etc/gitlab/gitlab-secrets.json/var/opt/gitlab/backups/1775028150_2026_04_01_13.6.7-ee_gitlab_backup.tar
其中前两个是配置文件,里面包含了密钥等敏感数据,是通过 gitlab-rake gitlab:backup:create 生成第三个备份文件后 gitlab 重点提到需要备份的文件。
docker compose 项目配置
获取版本号:
cat /opt/gitlab/embedded/service/gitlab-rails/VERSION
13.6.7-ee在 docker hub 上找到了对应版本的 linux/amd64 的镜像 gitlab/gitlab-ee:13.6.7-ee.0。
在和 deepseek 一阵 battle,结合之前的共享网络,有了下面的最终版的 docker compose 配置文件:
services:
gitlab:
image: gitlab/gitlab-ee:13.6.7-ee.0
container_name: gitlab
env_file: ./.env
ports:
- '2222:22'
networks:
- internal
- shared
restart: always
volumes:
- ./config:/etc/gitlab
- ./logs:/var/log/gitlab
- ./data:/var/opt/gitlab
- ./backups:/var/opt/gitlab/backups
healthcheck:
test: ["CMD-SHELL", "gitlab-healthcheck --fail || exit 1"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
hostname: 'gitlab.seasidecrab.com'
environment:
GITLAB_OMNIBUS_CONFIG: |
external_url 'https://gitlab.seasidecrab.com'
nginx['listen_port'] = 80
nginx['listen_https'] = false
nginx['proxy_set_headers'] = {
"X-Forwarded-Proto" => "https",
"X-Forwarded-Ssl" => "on"
}
gitlab_rails['gitlab_shell_ssh_port'] = 2222
networks:
internal:
driver: bridge
shared:
external: true
name: shared-services项目目录(可自行创建) /root/gitlab_project,.env 文件放了项目名的配置 COMPOSE_PROJECT_NAME=gitlab。
2222 端口是为 SSH 协议准备的,之前没有支持,走的是 http 协议。sudo netstat -tlnp | grep :2222 确认端口没有被占用。环境变量里配了一些内容,不确定是否生效了,反正在 gitlab.rb 中也做了对应的修改。
将 gitlab.rb 和 gitlab-secrets.json 放到 config 目录下,将备份文件放到 backups 目录下,然后执行以下的文件权限配置:
cd /root/gitlab_project
sudo chown -R 998:998 config logs data backups
sudo chmod 755 config logs data backups
sudo chmod 644 ./config/gitlab.rb
sudo chmod 600 ./config/gitlab-secrets.json # 密钥文件需要更严格的权限启动服务
跟之前一样,直接拉取报错,获取不到,试了多个国内镜像源都没用,阿里云的 ACR 镜像加速地址也没用。还是本地开 VPN,然后拉取指定服务器架构的镜像:
docker pull --platform linux/amd64 gitlab/gitlab-ee:13.6.7-ee.0
# 检查镜像架构
docker inspect gitlab/gitlab-ee:13.6.7-ee.0 | grep Architecture
"Architecture": "amd64",
# 保存为 tar 压缩包
docker save -o gitlab-ee-13.6.7.tar gitlab/gitlab-ee:13.6.7-ee.0
# 上传到服务器载入
docker load -i gitlab-ee-13.6.7.tar打包部分没有采用,因为文件太大,上传浪费流量。且考虑后续复用性,使用阿里云的 ACR 仓库服务,将其上传到新建的 gitlab 仓库,之后再从服务器上拉取。
拿到镜像的前缀是阿里云地址+空间名+镜像名:镜像版本号,要么修改 docker-compose.yml 配置文件中的镜像地址,要么重新打一下标签:
docker images
xxx/gitlab-ee:13.6.7-ee.0 c941242a1d17 3.48GB 976MB
docker tag c941242a1d17 gitlab/gitlab-ee:13.6.7-ee.0docker compose up -d 尝试启动容器,并修改 https-portal 配置,添加 gitlab.seasidecrab.com -> http://gitlab:80 重新生成,以便后续可以域名直接访问查看到页面情况。
恢复数据
# 查看运行中的容器
docker compose ps
# 查看日志
docker compose logs -f
# 恢复数据
docker exec -it gitlab bash
gitlab-ctl stop puma
gitlab-ctl stop sidekiq
# 1775028150_2026_04_01_13.6.7-ee_gitlab_backup,不包含后面的 _gitlab_backup,只是时间戳
gitlab-rake gitlab:backup:restore BACKUP=1775028150_2026_04_01_13.6.7-ee
gitlab-ctl restart
exit解决访问 502 问题
备份还原之后,访问 502 Bad Gateway,检查日志发现是容器 80 端口服务被拒。
# 查看容器中启动服务的状态
docker exec gitlab gitlab-ctl status、
# 查看 nginx 启动状态
docker exec gitlab gitlab-ctl status nginx检查发现没有 nginx 服务状态。然后想到之前的服务器上是使用了本地的 httpd 服务做反向代理,gitlab 自带的 nginx 是被关闭掉的。
httpd 中关于 gitlab 的主机配置:
<VirtualHost *:80>
ServerName gitlab.seasidecrab.com
ProxyRequests off
ProxyPass / http://127.0.0.1:8090/
ProxyPassReverse / http://127.0.0.1:8090/
<proxy *:80>
Order deny,allow
Allow from all
</proxy>
ErrorLog "/alidata/log/httpd/gitlab-error.log"
CustomLog "/alidata/log/httpd/gitlab.log" common
</VirtualHost>之前 gitlab.rb 中的配置:
nginx['enable'] = false
gitlab_workhorse['listen_addr'] = "127.0.0.1:8090"修改 gitlab.rb 配置
# 启用 nginx
nginx['enable'] = true
nginx['listen_port'] = 80
nginx['listen_https'] = false
# 外部访问地址
external_url 'https://gitlab.seasidecrab.com'
# 告诉 GitLab 通过 HTTPS 访问,但内部使用 HTTP
nginx['proxy_set_headers'] = {
"X-Forwarded-Proto" => "https",
"X-Forwarded-Ssl" => "on"
}
# 确保 Unicorn 配置正确(不知道干嘛的,但修改了一下)
unicorn['listen'] = '127.0.0.1'
unicorn['port'] = 8080配置生效并检查服务状态:
# 保存并退出后,重新配置
gitlab-ctl reconfigure
# 4. 启动 nginx
gitlab-ctl start nginx
# 5. 检查服务状态
gitlab-ctl status
# 6. 测试本地访问
curl -I http://localhost:80
# 7. 退出容器
exit修复 nginx 无法创建 PID 文件
访问页面变成了 gitlab 页面,但依然是 502:
502
Whoops, GitLab is taking too much time to respond.
Try refreshing the page, or going back and attempting the action again.
Please contact your GitLab administrator if this problem persists.检查 nginx 配置状态:
/opt/gitlab/embedded/sbin/nginx -t
nginx: [alert] could not open error log file: open() "/opt/gitlab/embedded/logs/error.log" failed (2: No such file or directory)
nginx: the configuration file /opt/gitlab/embedded/conf/nginx.conf syntax is ok
2026/04/01 09:59:26 [emerg] 6555#0: open() "/opt/gitlab/embedded/logs/nginx.pid" failed (2: No such file or directory)
nginx: configuration file /opt/gitlab/embedded/conf/nginx.conf test failed问题在于 nginx 无法创建 PID 文件 - 导致 nginx 无法启动
解决方案:
1. 创建缺失的目录并修复权限
# 进入容器
docker exec -it gitlab bash
# 创建缺失的目录
mkdir -p /opt/gitlab/embedded/logs
chown -R git:git /opt/gitlab/embedded/logs
# 创建 nginx 需要的目录
mkdir -p /var/opt/gitlab/nginx
chown -R git:git /var/opt/gitlab/nginx
# 创建 PID 目录
mkdir -p /opt/gitlab/embedded/logs
chown git:git /opt/gitlab/embedded/logs
# 创建临时目录
mkdir -p /opt/gitlab/embedded/temp
chown -R git:git /opt/gitlab/embedded/temp2. 修复 nginx 配置
# 检查 nginx 配置中的路径
cat /var/opt/gitlab/nginx/conf/nginx.conf | grep -E "pid|error_log"
# 创建错误日志文件
touch /opt/gitlab/embedded/logs/error.log
chown git:git /opt/gitlab/embedded/logs/error.log
# 创建 PID 文件
touch /opt/gitlab/embedded/logs/nginx.pid
chown git:git /opt/gitlab/embedded/logs/nginx.pid3. 启动 nginx
# 重新配置 GitLab
gitlab-ctl reconfigure
# 启动 nginx
gitlab-ctl start nginx
# 检查 nginx 状态
gitlab-ctl status nginx
# 测试 nginx 连接
curl -I http://localhost:80此时测试本地访问变成 302 重定向,访问页面 ok!
SSH(端口 2222)协议的使用
SSH 克隆仓库(指定端口)
# 标准 SSH 克隆(需要指定端口)
git clone ssh://git@gitlab.your-domain.com:2222/username/project.git
# 或者配置 SSH config 简化
cat >> ~/.ssh/config << EOF
Host gitlab.your-domain.com
Port 2222
EOF
# 配置后可以使用标准格式
git clone git@gitlab.your-domain.com:username/project.git 本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。
海滨擎蟹
微信
支付宝