ARTICLE DETAIL

资讯详情

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

Docker部署GitLab全攻略:环境一致性、迁移备份与漏洞修复

Docker部署GitLab全攻略:环境一致性、迁移备份与漏洞修复 1. 为什么我最终选择了Docker方式部署GitLab先交代背景。我最早是在一台云服务器上用官方Omnibus包装的GitLab后来换机器、迁移数据、升级版本每个环节都踩了不少坑。Omnibus包本身封装得很好但它和操作系统耦合太深升级时一旦依赖库冲突轻则服务起不来重则数据库表结构对不上只能从头备份恢复。后来我给团队搭内部代码仓库改用Docker部署GitLab实测下来省心非常多——环境隔离、升级回滚、迁移备份都是容器化那一套标准操作省掉了系统层面的各种纠缠。Docker部署GitLab解决的核心问题有三个环境一致性GitLab对系统库和依赖有严格要求容器镜像把这些全部锁死本机和服务器上跑的是同一套环境不会再出现在我机器上好好的到服务器就起不来的尴尬。升级和回滚简单换一个镜像Tag重新起容器就行挂掉了大不了用旧镜像恢复。Omnibus升级要是出了问题想退回旧版本相当痛苦。迁移成本极低拷贝数据卷目录到新机器一条命令就能把整个服务搬过去连系统都不用重新配。这篇文章适合谁看想在自己服务器或本机快速搭一个GitLab做个人代码仓库的朋友小团队打算自建内网GitLab来管理项目的人以及已经在用Docker但被GitLab配置问题卡住的人。我会把从零部署到日常使用中真正会踩的坑都写出来不写废话尽量让读者照着操作就能跑起来。需要说明的是本文的部署步骤基于官方gitlab/gitlab-ce镜像的常见实践Docker和GitLab版本迭代较快但核心思路是稳定的。有些环境细节会因系统不同略有差异我会在对应位置标注。2. 部署前的准备工作硬件底线、Docker环境与端口规划2.1 内存和CPU到底要给多少GitLab是出了名的内存大户它内置了PostgreSQL、Redis、Nginx、Sidekiq、Prometheus等一系列组件。官方文档写的最低配置是4GB内存但说句实话2GB的小机器强行跑也不是不行只是随时可能OOM内存耗尽表现为容器反复重启、页面加载极慢、git clone直接超时。我个人的实际经验是场景建议配置说明个人测试/体验2核、4GB跑通流程可以别开太多项目小团队内部仓库5-10人4核、8GB日常使用基本流畅团队主力代码托管20人以上8核、16GB还要考虑并发CI构建的话建议更高如果你只有1GB内存建议换个思路不要硬上GitLab否则排障时间比使用时间还长。另外单独给容器设置内存限制时不要只盯着-m参数GitLab自身通过环境变量也能控制部分组件的行为后面我会专门讲如何给它减负。2.2 Docker环境安装的常见坑Linux环境下Docker CE安装一般就是走官方yum/apt源这里不重复。Windows和macOS用户则要装Docker Desktop这里面有几个高频问题我顺手提一下Windows下提示virtualisation support wasnt detected这是因为Hyper-V或WSL2没有启用或者是主板VT-x没开。装Docker Desktop之前在控制面板-程序和功能-启用或关闭Windows功能里勾选Hyper-V和适用于Linux的Windows子系统重启后再装如果你用的是Windows 11确认一下是否启用了基于WSL2的后端。Linux下docker命令报权限错误permission denied while trying to connect to the Docker daemon socket这属于当前用户不在docker组里。执行sudo usermod -aG docker $USER然后重新登录终端。Docker网络不通容器内能访问外网但无法解析域名的话多半是DNS配置问题。可以给Docker daemon配置/etc/docker/daemon.json写入以下内容后执行systemctl restart docker。{ dns: [223.5.5.5, 114.114.114.114] }这个坑在部分云服务器上比较常见建议一开始就配好省得后续排查。2.3 端口规划80和22是最大的坑GitLab对外主要暴露三个服务HTTP默认80、HTTPS默认443、SSH默认22。但问题来了云服务器上80端口常常已经被Nginx或其他Web服务占用22端口是服务器SSH登录端口肯定不能直接给GitLab用。所以部署前必须提前想好端口映射方案我的推荐做法是HTTP端口映射为80:80如果80被占用就映射为8080:80访问地址相应变成http://your-server-ip:8080。SSH端口映射为2222:22这样用户clone仓库时走的是ssh://gityour-server-ip:2222/group/project.git不影响服务器本身的SSH登录。HTTPS端口除非你有正式证书否则前期不需要映射后续要启用再改配置。这里有个细节容易忽略外部SSH端口一旦改成2222GitLab对外展示的clone地址会自动带上端口号吗不会需要你在环境变量或gitlab.rb里额外配置gitlab_rails[gitlab_shell_ssh_port]这一步不设置用户复制出来的clone地址是错的。下面部署命令里我会写清楚。2.4 数据目录规划容器是一次性的数据必须挂载到宿主机。推荐单独建一个专用目录比如/data/gitlab下面分三个子目录configGitLab的配置文件包括gitlab.rb、gitlab-secrets.json。logs日志目录排障全靠它。data仓库、数据库、上传文件都在这。把这三个目录独立挂载是为了备份时只拷贝很明确的内容也方便以后做数据卷迁移。如果不挂载这三个目录就直接删容器那数据也跟着没了切记。3. 完整的部署流程从docker run到docker compose3.1 一条命令跑通的初始部署版本选择上优先gitlab/gitlab-ce:latest如果想求稳建议锁定一个大版本的最新补丁版比如gitlab/gitlab-ce:16.11.x-ce.0这种。前期先用latest跑通流程也完全可以。先给一个最简单、适合个人使用的docker run命令sudo docker run --detach \ --hostname gitlab.example.com \ --publish 8080:80 \ --publish 2222:22 \ --name gitlab \ --restart unless-stopped \ --volume /data/gitlab/config:/etc/gitlab \ --volume /data/gitlab/logs:/var/log/gitlab \ --volume /data/gitlab/data:/var/opt/gitlab \ --shm-size 256m \ gitlab/gitlab-ce:latest逐个解释这些参数--hostname设置容器内部的主机名这个值会直接影响GitLab生成的clone地址和重定向地址。如果现在还没有域名就先填服务器IP比如--hostname 192.168.1.100等有域名了再改。--publish 8080:80宿主机8080端口映射到容器80端口访问http://IP:8080。--publish 2222:22宿主机2222端口映射到容器SSH端口。--restart unless-stopped服务器重启后自动拉起容器非常实用不要省略。--shm-size 256mGitLab的Prometheus和Puma对共享内存有一些需求太小会导致启动异常官方推荐256m。执行后用docker logs -f gitlab观察启动日志。首次启动需要初始化数据库和各类组件耐心等3-5分钟看到gitlab Reconfigured!字样后访问http://IP:8080。3.2 修改SSH外部端口否则clone地址是错的上面命令只是把2222映射给了容器内的22但GitLab并不知道外部用户用的是2222。首次启动后需要修改配置文件告知它sudo docker exec -it gitlab /bin/bash进入容器后或者直接在宿主机编辑挂载出来的/data/gitlab/config/gitlab.rb设置gitlab_rails[gitlab_shell_ssh_port] 2222然后执行gitlab-ctl reconfigure等待重配完成。这一步做完项目页面复制的SSH clone地址就自动带上:2222了。3.3 推荐docker compose方式可维护性高很多docker run适合快速验证但参数多、不好维护。实际部署我强烈建议用docker compose把配置固化下来每次改动都有据可查。创建docker-compose.ymlversion: 3.8 services: gitlab: image: gitlab/gitlab-ce:latest container_name: gitlab restart: unless-stopped hostname: gitlab.example.com ports: - 8080:80 - 2222:22 volumes: - /data/gitlab/config:/etc/gitlab - /data/gitlab/logs:/var/log/gitlab - /data/gitlab/data:/var/opt/gitlab shm_size: 256m environment: GITLAB_ROOT_PASSWORD: your-strong-password-here GITLAB_ROOT_EMAIL: adminexample.com注意GITLAB_ROOT_PASSWORD这个环境变量它只会在首次初始化时生效如果目录已有数据则不起作用。我一般建议用这种方式直接设置初始root密码避免去读一串临时密码的麻烦。启动命令docker compose up -d后续更新版本就两步docker compose pull docker compose up -d容器会自动基于新镜像重建配置和数据都保留在挂载目录里。3.4 数据卷迁移的通用方法如果以后要换机器整个流程可以压缩成三步停容器docker compose down。打包整个/data/gitlab目录。在新机器上解压到同一路径重新docker compose up -d。注意一点config/gitlab-secrets.json这个文件必须一起迁移否则数据库里的加密内容无法解密项目代码倒还好但部分功能如webhook、2FA会异常。4. 部署后不能忽略的配置内存优化、备份与安全4.1 给GitLab减负拯救小内存服务器我遇到的第一个实际问题是4GB云服务器跑默认配置内存占用长期在85%以上。GitLab默认启动了一堆组件对个人和小团队来说很多是冗余的。通过修改gitlab.rb可以显著降低内存占用。# 关闭监控组件Prometheus和Grafana prometheus_monitoring[enable] false # 关闭不需要的依赖服务 gitaly[enable] true redis_exporter[enable] false postgres_exporter[enable] false node_exporter[enable] false # 限制Sidekiq并发数 sidekiq[max_concurrency] 5 # 减少Puma worker进程数 puma[worker_processes] 2 puma[min_threads] 1 puma[max_threads] 4改完后执行gitlab-ctl reconfigure和gitlab-ctl restart。实测在4GB机器上内存占用能从5GB左右降到2.5GB左右效果立竿见影。当然如果团队规模大、并发访问高别盲目关监控。4.2 定时备份机制GitLab自带备份命令挂载的数据卷里执行sudo docker exec -it gitlab gitlab-backup create备份文件会生成在/var/opt/gitlab/backups对应宿主机目录就是/data/gitlab/data/backups。建议配合crontab做定时任务0 2 * * * docker exec gitlab gitlab-backup create CRON1 /var/log/gitlab-backup.log 21恢复操作sudo docker exec -it gitlab gitlab-backup restore BACKUP一串时间戳注意备份文件建议再同步到其他机器或对象存储只放在同一台服务器上硬盘坏了就全没了。这个不用我说大家也懂但很多人就是懒得做。4.3 高危漏洞修复核心是别停留在老版本热搜词里有gitlab高危漏洞修复方案GitLab历史上出现过多起严重漏洞比如被广泛利用的上传接口RCE漏洞CVE-2021-22205和后来的XSS/SSRF类漏洞。修复方案总结起来很简单升级到官方发布的安全修复版本没有其他捷径。用Docker部署的最大优势在这一刻体现得淋漓尽致一条命令完成大版本升级docker compose pull docker compose up -d升级前注意版本路径GitLab不支持跨越太多大版本直接升级官方升级路径一般要求逐个大版本走。如果你是16.x想升18.x先升到17.x再升18.x。建议参考官方升级文档的路径表。另外将GitLab实例暴露到公网后建议第一时间关闭公开注册见下文4.4。设置强密码和两步验证。在安全组层面限制管理后台页面的访问IP。4.4 关闭注册和访问控制默认情况下GitLab的注册页面是开放的任何人都可以注册账号。如果是团队内部使用第一件事就是关掉它。操作方法进入Admin Area设置在Sign-up restrictions里取消勾选Sign-up enabled。或者直接在gitlab.rb里设置gitlab_rails[gitlab_signup_enabled] false如果想限制IP段访问建议在服务器安全组/防火墙层面做比应用层更可靠。5. 高频问题排查实录启动失败、端口冲突、IDE登录报错5.1 gitlab启动不了先看这三个原因容器反复重启或健康检查不通过90%是下面三种情况内存不足。表现是docker logs里出现Killed字样或者容器Started后几十秒又Exited。这种问题加内存或者按4.1的配置缩减组件立竿见影。端口被占用。表现是docker: Error response from daemon: driver failed programming external connectivity。用ss -lntp | grep 80查一下端口占用或者换个映射端口。磁盘空间满了。GitLab的仓库数据增长很快df -h会发现根分区占用100%容器反复启动失败。清理/var/lib/docker下没用的镜像和容器或者给挂载目录扩容。排查顺序建议先看健康状态docker ps -a再看日志docker logs -f gitlab然后按上面三类对号入座。不要一上来就删容器重装很多问题删了重来还会复现。5.2 Nginx在80端口怎么和GitLab共存很多服务器本来就有Nginx反代其他站点GitLab也想占80端口冲突必然发生。两种解法第一种最简单的GitLab映射到其他端口8080外部访问路径加端口号。适合内网环境缺点是URL不优雅。第二种GitLab映射到80用宿主机Nginx做反向代理转发到容器。Nginx配置示例server { listen 80; server_name git.example.com; location / { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }同时要修改GitLab配置告知它外部访问地址external_url http://git.example.com注意修改external_url后执行gitlab-ctl reconfigure否则重定向地址还是容器内部的主机名。5.3 IDEA/PyCharm登录报错GitLab versions older than 14.0 are not supported这个报错在热搜词里出现了多次典型的JetBrains系IDE连接GitLab时报错完整信息类似Login failed. GitLab versions older than 14.0 are not supported. Log in via URL...原因很简单新版JetBrains IDE的GitLab集成只支持14.0以上版本你服务器上装的GitLab版本太老被插件拒了。同时这个报错还有另一种常见成因——IDE插件默认尝试通过API Token方式登录但GitLab账号没有配置个人访问令牌Personal Access Token。解决办法分两种如果GitLab版本确实低于14.0建议按4.3的方案升级。老版本不仅有兼容性问题安全风险更高。如果版本不低但仍然报错那就去GitLab生成一个个人访问令牌Personal Access Token操作路径用户设置Settings - Access Tokens勾选api作用域生成后在IDE里用Token登录而不是用账号密码。个人访问令牌这东西还有一个常见用途在CI/CD脚本里代替密码做git push认证也是推荐的安全做法。5.4 Docker权限、网络问题的通用解决顺序之前提过docker命令权限问题这里再补充一个高频场景docker compose up -d时拉取镜像慢或失败这在国内网络环境下经常遇到。解决方案是配置镜像加速器在/etc/docker/daemon.json中给registry-mirrors字段填上可用的加速地址然后重启Docker。网络不通的另一个常见表现是容器能启动但GitLab页面打不开。先检查宿主机防火墙sudo firewall-cmd --list-ports sudo ufw status确认8080端口在防火墙放行名单里。云服务器的话还要检查安全组规则。这个顺序别搞反先查防火墙和安全组再查容器内服务。6. 日常使用中的效率技巧项目导入、IDE协作与权限控制6.1 一键导入已有项目GitLab支持从Gitee、GitHub、Bitbucket甚至另一个GitLab实例导入项目。路径是新建项目 - Import project - 选择对应平台填上访问令牌即可。这个功能在小团队迁移代码时极其有用不用在本地先pull再push。6.2 VS Code、IntelliJ IDEA、PyCharm连接GitLab在IDE里提交代码到GitLab通用的操作路径就是先配置好Git然后clone项目或者add remote。重点讲两个细节clone地址统一。项目页面会显示HTTP和SSH两种地址在配置了2222端口的外部映射后SSH地址形如ssh://gitIP:2222/group/project.git直接复制这个地址clone就行不用手动改。SSH Key配置。在GitLab用户设置里添加公钥Settings - SSH Keys本地的~/.ssh/id_rsa.pub内容粘贴进去即可。配置完成后IDE里的git操作走SSH协议就不会反复要密码。6.3 Developer角色能提交到master吗这个问题在团队协作场景里几乎每周都有人问。GitLab默认的分支保护策略下master/main分支只有Maintainer及以上角色可以推送代码Developer角色直接push会被拒绝报错信息会提示you are not allowed to push code to this project。但这不意味着Developer没法把代码合入master正确流程是新建功能分支 - 推送分支 - 发起Merge Request - 由Maintainer审查并合并。这个流程本身就是代码评审的核心场景。如果团队确实希望Developer也能直接推送到master可以在项目的Settings - Repository - Protected branches里把Allowed to push的权限改成Developer或者把master分支的保护关掉。6.4 GitLab CI/CD快速上手GitLab自带的CI/CD功能是团队用它的一个重要理由。在项目根目录创建.gitlab-ci.yml就会自动触发流水线。下面是一个最简单的示例stages: - test - build test-job: stage: test script: - echo running tests... build-job: stage: build script: - echo building project...Runner可以装在单独的机器上也可以用Docker方式部署gitlab/gitlab-runner镜像。注册Runner时填的URL和token在项目Settings - CI/CD - Runners里看。跑通一次流水线后你会发现代码提交后自动构建和测试比人肉在本地跑舒服太多。最后分享两个实际操作中的小技巧第一个是服务器重启后的服务拉起问题。很多人配了--restart unless-stopped以为万事大吉但有时候Docker服务本身没启动容器自然起不来。建议把systemctl enable docker设置一下确保Docker随系统自动启动。实测服务器意外重启后GitLab能自己活过来省了很多麻烦。第二个是别忽略gitlab.rb的改动习惯。每次修改配置里的任何参数先复制原文件备份再改然后reconfigure。我在排查问题的时候经常需要对比配置改之前和改之后的行为差异有了备份能省半个小时的回忆时间。Docker部署GitLab这件事核心就是把复杂的环境问题隔离掉让GitLab本身成为可控的、可替换的组件。只要磁盘挂载和数据卷做对了版本升级和故障恢复都不吓人。如果照着这篇文章操作仍然有问题大概率不是你操作不对而是某个环境细节没对齐不妨回到日志和端口状态这两个最基本的地方重新检查一遍。
返回列表