ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

使用 Docker 部署 GitLab:再配置external_url 无法访问

使用 Docker 部署 GitLab:再配置external_url 无法访问

使用 Docker 部署 GitLab 的完整实践指南

在现代 DevOps 工作流中,私有代码仓库是必不可少的基础设施。GitLab 凭借其强大的代码管理、CI/CD 和项目管理功能,成为很多团队的首选。本文将以最简洁的方式,记录如何使用 Docker 在一台服务器上快速部署 GitLab CE 版本,并分享过程中容易遇到的陷阱和解决方法。

环境与准备

  • 服务器:一台 Linux 主机(本文以 IP192.168.1.156为例,请根据实际情况替换)
  • Docker:已安装 Docker Engine
  • 持久化目录:提前创建用于存放配置、日志和数据的宿主机目录
    mkdir-p/usr/local/gitlab/{config,logs,data}

启动 GitLab 容器

使用的docker run命令如下,附带详细说明:

sudodockerrun-d\--hostname192.168.1.156\--namegitlab\--restartalways\--shm-size=1g\-p8012:8012\-v/etc/localtime:/etc/localtime:ro\-v/usr/local/gitlab/config:/etc/gitlab\-v/usr/local/gitlab/logs:/var/log/gitlab\-v/usr/local/gitlab/data:/var/opt/gitlab\-eGITLAB_OMNIBUS_CONFIG="external_url 'http://192.168.1.156:8012';"\gitlab/gitlab-ce:latest

参数解读:

  • --hostname:设置 GitLab 实例的主机名,这里直接使用内网 IP,实际生产环境建议替换为可解析的域名。
  • --restart always:保证容器在退出或宿主机重启后自动启动。
  • shm-size: 配置容器共享内存大小。
  • 端口映射
    • 8012:8012→ HTTP 访问端口,也是我们浏览器访问的入口(容器内默认为80)
    • 8013:22→ SSH 端口,用于 Git 操作(注意宿主机 22 端口通常已被占用,此处映射为 8013 避免冲突,不适用ssh可以忽略)
    • 8011:443→ HTTPS 访问端口(如需证书需自行配置,否则可以忽略)
  • 卷挂载(核心)
    • /etc/localtime:ro:保持容器内时间与宿主机同步,避免时区问题。
    • /usr/local/gitlab/config/etc/gitlab:存放 GitLab 配置文件,包括gitlab.rb以及初次启动时生成的初始密码文件initial_root_password
    • /usr/local/gitlab/logs/var/log/gitlab:运行日志,排错必备。
    • /usr/local/gitlab/data/var/opt/gitlab最重要的数据目录,代码仓库、用户信息、Issue、上传附件等所有持久化数据都保存在这里,务必妥善备份。

首次启动会拉取镜像并初始化数据库,耗时可能较长(约 2-5 分钟),可使用docker logs -f gitlab查看进度,直到出现gitlab Reconfigured!之类信息即表示启动成功。

获取并修改 root 初始密码

GitLab 从较新版本开始,默认不再使用固定的初始密码,而是在初次启动时随机生成一个密码,并存储在容器的/etc/gitlab/initial_root_password文件中。由于我们已将config目录挂载出来,因此可以直接在宿主机查看:

cat/usr/local/gitlab/config/initial_root_password

输出示例:

# WARNING: This value is valid only in the following conditions # 1. If provided manually (either via `GITLAB_ROOT_PASSWORD` environment variable or via `gitlab_rails['initial_root_password']` setting in `gitlab.rb`, it is provided directly before database is seeded for the first time (usually, the first reconfigure run). # ... (注释省略) Password: 9aBcD3FgHijkLm

注意:该密码文件会在 24 小时后被自动删除,因尽快登录并修改 root 密码。

可以通过命令行重置密码:

# 进入容器内部dockerexec-itgitlab /bin/bash# 执行密码重置,按照提示输入两次新密码gitlab-rake"gitlab:password:reset[root]"

或者直接一条命令搞定:

dockerexec-itgitlab gitlab-rake"gitlab:password:reset[root]"

按照提示输入新密码后,即可使用新密码登录。

访问 GitLab 并登录

在浏览器中访问http://192.168.1.156:8012,使用用户名root和设置(或查到的)密码登录。

成功登录后,可以:

  • 创建项目、管理用户
  • 配置 SSH 密钥(若使用 SSH 方式推送代码,需将远端地址中的端口指定为8013,例如ssh://git@192.168.1.156:8013/username/repo.git
  • 调整系统设置(建议在/usr/local/gitlab/config/gitlab.rb中修改外部 URL 等配置后,执行docker exec -it gitlab gitlab-ctl reconfigure使其生效)

遇到问题

原启动命令

sudodockerrun-d\--hostname192.168.233.156\--namegitlab\--restartalways\-p8012:80\-v/etc/localtime:/etc/localtime:ro\-v/usr/local/gitlab/config:/etc/gitlab\-v/usr/local/gitlab/logs:/var/log/gitlab\-v/usr/local/gitlab/data:/var/opt/gitlab\swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/gitlab/gitlab-ce:latest

一. 频繁出现 500 或 502 错误
部署后偶尔出现页面 500/502 错误,刷新几次可能恢复正常,这通常不是 GitLab 服务本身崩溃,而是由服务器磁盘空间不足引起的。
后台大量打印如下类似日志:
{“severity”:“DEBUG”,“time”:“2026-08-04T03:14:10.987Z”,“message”:“/opt/gitlab/embedded/lib/ruby/gems/3.2.0/gems/prometheus-client-mmap-1.2.10-x86_64-linux-gnu/lib/prometheus/client/mmaped_dict.rb:46:inupsert_entry'\n/opt/gitlab/embedded/lib/ruby/gems/3.2.0/gems/prometheus-client-mmap-1.2.10-x86_64-linux-gnu/lib/prometheus/client/mmaped_dict.rb:46:inwrite_value’\n/opt/gitlab/embedded/lib/ruby/gems/3.2.0/gems/prometheus-client-mmap-1.2.10-x86_64-linux-gnu/lib/prometheus/client/mmaped_value.rb:139:inwrite_value'\n/opt/gitlab/embedded/lib/ruby/gems/3.2.0/gems/prometheus-client-mmap-1.2.10-x86_64-linux-gnu/lib/prometheus/client/mmaped_value.rb:48:inblock in set’\n/opt/gitlab/embedded/lib/ruby/gems/3.2.0/gems/prometheus-client-mmap-1.2.10-x86_64-linux-gnu/lib/prometheus/client/mmaped_value.rb:44:insynchronize'\n/opt/gitlab/embedded/lib/ruby/gems/3.2.0/gems/prometheus-client-mmap-1.2.10-x86_64-linux-gnu/lib/prometheus/client/mmaped_value.rb:44:inset’\n/opt/gitlab/embedded/lib/ruby/gems/3.2.0/gems/prometheus-client-mmap-1.2.10-x86_64-linux-gnu/lib/prometheus/client/gauge.rb:28:inset'\n/opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/metrics/samplers/threads_sampler.rb:41:inset_running_threads’\n/opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/metrics/samplers/threads_sampler.rb:33:inblock in sample'\n/opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/metrics/samplers/threads_sampler.rb:30:ineach’\n/opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/metrics/samplers/threads_sampler.rb:30:insample'\n/opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/metrics/samplers/base_sampler.rb:30:insafe_sample’\n/opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/metrics/samplers/base_sampler.rb:80:inblock in run_thread'\n/opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/metrics/samplers/base_sampler.rb:89:inblock in wrap_sampler’\n/opt/gitlab/embedded/lib/ruby/gems/3.2.0/gems/activesupport-7.1.5.1/lib/active_support/execution_wrapper.rb:92:inwrap'\n/opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/metrics/samplers/base_sampler.rb:89:inwrap_sampler’\n/opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/metrics/samplers/base_sampler.rb:80:inrun_thread'\n/opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/daemon.rb:58:inblock (2 levels) in start’”}
{“severity”:“WARN”,“time”:“2026-08-04T03:14:10.988Z”,“message”:“writing value to /dev/shm/gitlab/puma/gauge_all_puma_2-0.db failed with unmapped file”}


问题分析
writing value to /dev/shm/gitlab/puma/gauge_all_puma_2-0.db failed with unmapped file表明,GitLab 尝试向 /dev/shm 目录写入文件时失败。/dev/shm 是Linux系统的共享内存(tmpfs) 目录,Docker容器默认大小通常仅为 64MB。
连锁反应:当 /dev/shm 空间耗尽,GitLab 的 prometheus-client-mmap 组件无法写入指标数据,便会不断重试并产生大量 DEBUG 和 WARN 级别日志。

解决方法

  1. 清理宿主机磁盘占用情况并清理。
  2. 增加 Docker 容器的共享内存大小
    –shm-size=1g 或者 --shm-size=512m

二. 创建仓库初始化地址以及仓库链接地址,都没带上8012端口(使用的是默认的80端口),无法访问和跳转。
GitLab容器因端口映射(宿主机8012→容器80)导致生成的链接丢失:8012,根源在于external_url未配置真实访问地址(默认不含端口)。解决方案:修改gitlab.rb中的external_url为http://IP:8012
解决方法
停止容器:docker stop gitlab
删除容器:docker rm gitlab
新建容器:
sudo docker run -d
–hostname 192.168.1.156
–name gitlab
–restart always
–shm-size=1g
-p 8012:8012
-v /etc/localtime:/etc/localtime:ro
-v /usr/local/gitlab/config:/etc/gitlab
-v /usr/local/gitlab/logs:/var/log/gitlab
-v /usr/local/gitlab/data:/var/opt/gitlab
-e GITLAB_OMNIBUS_CONFIG=“external_url ‘http://192.168.1.156:8012’;”
gitlab/gitlab-ce:latest

插曲:之前添加 -e GITLAB_OMNIBUS_CONFIG=“external_url ‘http://192.168.1.156:8012’;” \后,依然使用 -p 8012:80导致无法访问。GitLab Omnibus 的 external_url 会直接决定容器内 Nginx 的监听端口。配置了 external_url ‘http://…:8012’ 后,容器内的 Nginx 便会监听 8012,而不再监听 80。因此 -p 8012:80 将宿主机请求转发到了容器内无人监听的 80 端口,导致无法连接。

安全与运维建议

  1. 密码与文件安全:务必在首次登录后修改 root 密码,并注意/usr/local/gitlab/config/initial_root_password文件的保密性。
  2. 数据备份:重点保护/usr/local/gitlab/data目录,可使用tar或 GitLab 自带的gitlab-backup命令定期备份并传输至异地。
  3. 网络与防火墙:若只对内网服务,建议在宿主机防火墙上仅开放需要的端口(如 8012),避免将 22 映射到公网。
  4. HTTPS 配置:生产环境建议配合 Nginx 反向代理或直接在 GitLab 配置中启用 SSL,此时需挂载证书文件并修改对应的external_url
  5. 时区一致性:挂载/etc/localtime保证了日志时间正确,对于排错和时间敏感型操作(如 CI 定时触发)很重要。

总结

通过 Docker 部署 GitLab 十分简便,只需一条docker run命令就能获得一个全功能代码托管平台。关键点在于:

  • 正确挂载数据卷,尤其是data目录,保证数据持久化。
  • 及时获取并修改 root 密码,避免因密码文件 24 小时自动删除而无法登录。
  • 注意磁盘空间健康,避免因空间耗尽导致服务异常。

如果在部署过程中遇到其他问题,欢迎在评论区交流讨论。


愿你我都能在各自的领域里不断成长,勇敢追求梦想,同时也保持对世界的好奇与善意!

返回列表