GitLab安装部署全攻略:多系统与Docker实战踩坑总结
这几年帮不同团队搭代码托管平台GitLab安装是绕不开的一道坎。2026年这一轮新版本迭代以后安装方式相比早期其实简化了不少官方对主流发行版都提供了现成的软件源但正因来源多、系统杂反而容易在依赖、权限、端口、默认配置这几个地方反复踩坑。这篇文章把我实际装过的几类环境完整走一遍从Ubuntu、Debian、CentOS/Rocky到Docker把每个环节背后的原因讲透顺便整理那些文档里不写、但一定会遇到的坑。无论你是刚接触GitLab准备自己搭一个还是打算迁移现有服务器都能在下面找到可以直接照抄的操作步骤。1. 安装前的版本与方案选型1.1 选CE还是EE别看到新版本就盲目上GitLab分成社区版和企业版两条线。社区版的功能对于绝大多数中小团队已经完全够用代码托管、Merge Request、CI/CD、容器镜像仓库都包含在内企业版多出来的主要是合规审计、高级安全扫描、大规模权限治理这类面向企业管控的功能而且需要授权文件才能启用。我的建议很直接自用或小团队直接选CE没必要为了追“最新版”三个字去碰EE。版本号也不是越新越适合你生产环境真正该用的是当前维护周期内的稳定版本小版本更新可以缓一缓。这里有个容易被忽略的授权问题GitLab的新版本和操作系统版本之间存在一套兼容关系。老旧发行版在安装新版GitLab时会遇到系统依赖库不齐全的情况比如glibc版本过低导致Ruby相关组件根本起不来。所以在选择GitLab版本之前第一步是确认自己的操作系统还处于维护周期内并且包管理器软件源正常可用。这是整个安装流程里优先级最高的一件事比任何命令都重要。1.2 硬件资源预算官方最低配置和实际体验差很多GitLab默认会带着PostgreSQL、Redis、Gitaly、Sidekiq、Puma一整套服务一起跑。官方写的最低4GB内存真实装完以后你会发现4GB只够服务启动和打开静态页面一旦有几个人同时跑CI内存立刻见底页面开始卡顿甚至直接502。我实际使用下来资源需求大概是这样使用场景内存CPU磁盘个人学习实验4GB2核40GB SSD小团队10人以下8GB4核100GB SSD团队50人左右16GB8核根据增长预留足够空间磁盘这一点特别提醒Git仓库本身的占用看着不大但GitLab的备份文件、容器镜像、CI构建产物都会慢慢堆起来尤其跑一段时间以后磁盘上涨速度比想象快很多。建议系统盘和数据盘分开数据盘单独挂载并且准备一个磁盘告警脚本。不要等磁盘100%之后再想起来处理那会儿可能连GitLab管理后台都进不去了。1.3 安装方式选型包管理器、Docker还是源码GitLab官方推荐的安装方式主要是两大类一类是原生包安装也就是deb/rpm安装包官方内部叫Omnibus方式另一类是Docker容器安装。源码安装现在已经明确不推荐依赖关系太复杂、升级难度大、维护成本极高除非有非常特殊的需求否则不要碰源码编译。原生包安装的本质是把GitLab运行时依赖的所有组件全部统一打进一个安装包由GitLab自己管理整套进程体系。这种方式的优势是性能好、和系统结合紧密日志、systemd服务管理都直观适合把GitLab作为长期生产服务的场景。Docker容器安装则是把GitLab跑在隔离环境里依赖容器镜像维护。它的优势是安装过程基本不污染宿主系统同一套 compose 配置在Ubuntu、CentOS、Windows、macOS上都能跑升级时换个镜像标签就行。特别适合那些不想在服务器上折腾一堆依赖、或者需要在一台机器上同时运行多套服务的人。两种方式没有绝对好坏看服务器定位。我自己在实际项目中通常这么判断专用服务器跑GitLab用原生包如果是一台机器上要跑多套服务或者想尝鲜新版又不想影响现有环境用Docker更干净。后面我把两条路的操作细节都写清楚。2. 不同系统的安装实操记录2.1 Ubuntu / Debian 系统安装全流程Ubuntu和Debian的安装步骤几乎一致。安装前先执行 apt-get update 把系统包索引更新到当前状态否则装到一半可能因为软件源太旧出现依赖冲突。Ubuntu上推荐直接使用官方仓库脚本添加GitLab源sudo apt-get update sudo apt-get install -y curl openssh-server ca-certificates perl curl -fsSL https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.deb.sh | sudo bash sudo apt-get install -y gitlab-ce脚本会自动在系统里注册GitLab的deb软件源配置文件写入 /etc/apt/sources.list.d/ 目录。安装完成后GitLab本体已经落到系统里但服务默认不启动需要先改配置再执行初始化。修改 /etc/gitlab/gitlab.rb 是安装后最重要的一步。找到 external_url 这一行改成自己规划的访问地址external_url http://gitlab.example.com随后执行sudo gitlab-ctl reconfigure这条命令会根据 gitlab.rb 生成全部配置、创建数据库、启动整套服务整个过程大概要跑几分钟。如果中间卡住多半是内存不足或磁盘空间不够可以另开一个终端用 dmesg 或 journalctl -xe 查看系统日志。Debian上的流程完全一样。唯一要留意的是Debian 12之后系统自带的sshd通常已经占用22端口后续配置GitLab SSH通道时要想办法和其他服务错开这个在第三章详细讲。2.2 CentOS / Rocky 系统安装全流程CentOS 7已经停止维护2026年继续维护的RHEL兼容系主流选择是Rocky Linux或AlmaLinux。如果服务器还在用CentOS 7请先规划迁移否则新版GitLab所需的依赖组件很多都装不上。Rocky和AlmaLinux上的安装命令sudo dnf install -y curl policycoreutils openssh-server openssh-clients postfix sudo systemctl enable sshd sudo systemctl start sshd curl -fsSL https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh | sudo bash sudo dnf install -y gitlab-ce安装完成后同样编辑 /etc/gitlab/gitlab.rb然后执行 reconfigure。这里有一个RHEL系独有的坑SELinux默认开启如果访问GitLab时出现页面权限异常、打不开、SSH clone失败这类现象很大可能是SELinux拦截了GitLab需要的网络权限。处理方式有两种一种是把SELinux转成宽松模式适合内部服务器或者不熟悉SELinux的人sudo setenforce 0 sudo sed -i s/^SELINUXenforcing/SELINUXpermissive/ /etc/selinux/config另一种是给GitLab需要的网络能力设置对应的布尔值适合更讲究安全策略的环境sudo setsebool -P httpd_can_network_connect on设置完可以通过 audit2why 查看SELinux日志判断是否还有其他布尔值需要打开。两个方案生效后都要重启相关服务再验证不要只在当前会话改了完事。2.3 Docker方式一套配置通吃所有系统最省心的跨系统方案是Docker。不管底层是Ubuntu还是CentOS又或者是Windows、macOS上的Docker Desktopcompose配置几乎一样只要镜像和端口映射一致运行行为就完全相同。先准备一份 docker-compose.ymlversion: 3.8 services: gitlab: image: gitlab/gitlab-ce:latest container_name: gitlab restart: always hostname: gitlab.example.com environment: GITLAB_OMNIBUS_CONFIG: | external_url http://gitlab.example.com ports: - 80:80 - 443:443 - 22:22 volumes: - gitlab_config:/etc/gitlab - gitlab_logs:/var/log/gitlab - gitlab_data:/var/opt/gitlab shm_size: 256m volumes: gitlab_config: gitlab_logs: gitlab_data:注意三个挂载目录配置目录、日志目录、数据目录必须全部持久化。很多人在这一步偷懒容器重建时没挂数据卷GitLab会用全新配置重新初始化相当于数据直接蒸发。所以即便只是测试环境也建议把数据挂到具名卷别用临时容器。启动命令docker compose up -d启动后检查状态docker compose ps docker logs -f gitlabDocker方式最明显的优势在升级环节。把镜像标签从 latest 换成指定版本然后重新创建容器就行。不过升级大版本前还是要先做数据备份这个原则任何安装方式都适用。2.4 Windows与macOS上的可行路径Windows和macOS作为桌面系统直接原生安装GitLab服务器端并不被官方支持。最顺的做法还是通过Docker Desktop跑。在Windows上安装Docker Desktop后把上面的docker-compose.yml直接拿过来执行。这里有个关键设置Docker Desktop默认只分配2GB内存给虚拟机这个量跑GitLab是远远不够的。打开Docker Desktop设置在Resources里把内存调到至少8GBCPU调到4核以上否则装完打开页面会反复出现502。macOS的情况类似。Apple Silicon芯片上跑GitLab性能没什么问题但同样要留意Docker Desktop的内存限制并且80、443端口可能被系统或其他服务占用需要先关掉冲突服务或者改端口映射。对于完全不熟悉命令行的用户Windows上还有一个选择是用WSL 2在WSL里装一个Ubuntu然后按照2.1的流程安装GitLab。这种方式比Docker Desktop更接近传统Linux服务器后期维护也更顺手适合想借机学习Linux运维的人。3. 初始化配置与启动后的关键细节3.1 external_url 决定后面所有链接external_url 是安装配置里最重要的一项。它不只是一个访问地址GitLab内部生成clone地址、Webhook回调地址、CI/CD里的仓库地址全部基于这个值拼接。所以地址要一次填对不然之后用户clone项目时会发现地址里带着内网IP或者错误端口。规划URL时记住这个对应关系访问方式external_url 填写直接用IP访问http://192.168.x.x用域名HTTP访问http://gitlab.example.com用域名HTTPS访问https://gitlab.example.com非80端口访问http://gitlab.example.com:8080如果配置HTTPS还需要准备证书。生产环境强烈建议直接上HTTPSGitLab默认的HTTP模式在局域网内还好一旦跨网络传输账号密码和代码内容都是明文风险非常大。证书可以用免费泛域名证书也能用自签证书但自签证书需要每台客户端手动导入实际维护体验比较麻烦。3.2 初始管理员密码和登录GitLab全新安装后不会让你在网页上先注册管理员而是自动生成一个随机密码存放在 /etc/gitlab/initial_root_password 文件里。这个文件只在首次reconfigure后保留24小时之后自动删除。登录方式是用 root 账号加初始密码进入后台第一件事就是修改密码。如果文件已经删除或者密码忘了可以在服务器上执行sudo gitlab-rake gitlab:password:reset[root]按提示输入新密码即可。这是管理员忘记密码后的标准恢复方式比直接改数据库表靠谱得多。3.3 常用配置项SSH端口、时区、邮件SMTPGitLab默认的SSH服务端口是22但很多服务器的22端口已经被系统sshd占用。此时需要修改配置gitlab_rails[gitlab_shell_ssh_port] 2222修改后执行 reconfigure用户的clone地址会变成 ssh://gitgitlab.example.com:2222/group/project.git 这种格式。注意这里的端口是GitLab SSH对外暴露的端口和系统sshd的端口是两回事别搞混。时间偏移问题在Docker容器里最常见。容器默认使用UTC时区如果不管提交记录、页面显示时间和本地时间会差好几个小时。处理办法是在容器环境变量里加 TZ设置成你所在时区的IANA标识同时在 GITLAB_OMNIBUS_CONFIG 里同步设置 gitlab_rails[time_zone]两个地方保持一致系统日志、Git提交时间、网页显示时间才能全部统一。邮件通知也是很容易被忽略的一块。比较推荐直接通过SMTP外发在 gitlab.rb 里配置gitlab_rails[smtp_enable] true gitlab_rails[smtp_address] smtp.example.com gitlab_rails[smtp_port] 587 gitlab_rails[smtp_user_name] gitlabexample.com gitlab_rails[smtp_password] password gitlab_rails[smtp_authentication] login gitlab_rails[smtp_enable_starttls_auto] true改完重新reconfigure然后在管理后台发送一份测试邮件确认通了。邮件不通会直接影响密码找回、用户接收通知这步别跳。3.4 启动后的基础检查安装完不要急着把地址丢给别人用先做一轮完整性检查。第一步用 gitlab-ctl status 确认所有组件都是 run 状态。第二步打开浏览器访问 external_url确认能看到登录页面。如果出现502先看内存占用和Puma日志。第三步实际操作一遍完整的“创建项目-克隆-提交-推送”流程。很多情况下页面看起来正常但SSH走不通或者clone地址错误都是在这一步才暴露出来。最后把备份服务配置好。GitLab自带备份命令可以放在crontab里每天执行sudo crontab -e 0 2 * * * /opt/gitlab/bin/gitlab-backup create CRON1备份文件默认放在 /var/opt/gitlab/backups建议同步到异地存储否则服务器磁盘坏了备份也跟着没。4. 安装与运行常见问题排查4.1 502 Bad Gateway到底是谁的锅502可以说是GitLab新手遇到最多的错误。这个提示本身说明Web层是通的真正出问题的是后端某个服务没起来或者返回异常。标准排查顺序是先看服务状态sudo gitlab-ctl status如果看到 puma 或 sidekiq 显示 down先逐个拉起sudo gitlab-ctl restart puma sudo gitlab-ctl restart sidekiq然后立刻看日志sudo gitlab-ctl tail puma sudo gitlab-ctl tail sidekiq502最常见的原因就是内存不足。GitLab组件多且重内存不够时内核OOM会把Puma或PostgreSQL直接杀掉表现为服务状态反复重启。处理方案是加内存或者把用不到的组件关掉。举一个常用优化不使用监控功能的话可以在 gitlab.rb 里关闭Prometheus相关组件prometheus_monitoring[enable] false这能省出大约1GB内存。只有4GB内存的机器关掉之后体验改善非常明显。4.2 端口冲突与绑定失败端口相关的问题分为两种。一种是系统里已经装了Nginx或Apache并占用80/443端口GitLab自带Nginx会绑定失败。处理办法是让现有服务让路或者干脆让GitLab使用其他端口在external_url里带上端口的同时修改nginx[listen_port] 8080另一种是GitLab内部服务默认的8080端口被系统其他进程占用。Puma默认监听127.0.0.1:8080冲突时reconfigure阶段会报 Address already in use 错误解决办法是修改Puma端口puma[port] 8181改完重新reconfigure验证。这类内部端口冲突排查起来比较费时间建议先执行 ss -lntp 或 netstat -lntp 把所有监听端口过一遍确认到底哪些端口已经被占。4.3 时间不同步带来的奇怪现象容器或虚机环境下如果宿主机没配置时间同步服务GitLab会出现一些看着非常诡异的问题Git提交时间不准确、CI构建日志时间混乱、SSL证书校验失败等。排查方式很简单先看当前时间date -R如果偏差很大就需要处理。Ubuntu/Debian上启用自动时间同步sudo timedatectl set-ntp trueCentOS/Rocky上确认chronyd在运行sudo systemctl enable --now chronydDocker容器里跑GitLab时间一般跟随宿主机但容器内设置错误的TZ还是会显示偏移。把时区环境变量统一设置好这类问题就能从根本上避免。4.4 升级失败与版本跨越的坑GitLab的升级不像普通软件那样随便升。官方对版本升级有明确策略不能跨大版本直接跳必须按顺序逐步升级。如果从很旧的版本直接升到最新reconfigure阶段会报数据库迁移错误这时候再回头补中间版本就很被动。升级前最重要的事是备份。我经历过一次升级到一半磁盘满了、数据没备份的情况最后靠前一天晚上的备份才救回来。所以升级流程总结为四步确认当前版本和目标版本之间没有跨大版本。执行数据备份gitlab-backup create。执行配置文件备份gitlab-ctl backup-etc。替换软件源版本号或镜像标签重新安装执行 reconfigure 并观察日志。如果升级后页面出现500错误先不要急着重装。优先查看日志sudo gitlab-ctl tail gitlab-rails大多数情况是数据库迁移卡住执行sudo gitlab-rake db:migrate再次检查。升级过程中如果实在找不到问题把当前版本的日志和配置发到社区请人帮忙看比自己盲目试验更有效。但前提仍然是数据有备份否则不要做任何盲目操作。4.5 常见问题速查表现象可能性处理建议页面502内存不足 / Puma挂了检查内存占用查看 gitlab-ctl tail puma安装时端口报错80/443或8080被占用修改external_url、nginx或Puma端口SSH clone端口不对gitlab-shell端口配置错误检查gitlab.rb里的gitlab_shell_ssh_port时间显示偏移时区或时间同步问题设置TZ开启时间同步服务升级后500数据库迁移未完成查看rails日志执行db:migrateroot密码丢失initial_password文件失效用gitlab-rake重置密码5. 安装之后的日常维护建议5.1 备份与恢复的完整套路备份是GitLab维护里最值得花时间搞清楚的环节。数据备份文件和配置文件是分开的必须都处理才算完整的恢复方案。数据备份sudo gitlab-backup create配置备份sudo gitlab-ctl backup-etc恢复数据时要保证GitLab版本和备份时的版本一致否则数据库结构不兼容恢复后大概率起不来。恢复命令sudo gitlab-backup restore BACKUP时间戳恢复完成后把 /etc/gitlab 目录下的配置文件恢复回去再执行sudo gitlab-ctl reconfigure sudo gitlab-ctl restart我个人的习惯是备份文件留三份本地保留最近7天异地同步一份重要节点比如升级前、重构前手动再存一份长期归档。备份策略可以简单但不能没有。5.2 资源监控的几个关键指标GitLab跑起来以后日常最需要关注三个指标内存、磁盘、服务进程状态。内存方面重点看 free 的输出只要可用内存长期低于500MB就要考虑加内存或调整组件开关。磁盘方面重点看 /var/opt/gitlab 所在分区使用率超过80%就该清理或扩容超过90%要立刻处理。服务进程方面用 gitlab-ctl status 查看是否有 down 状态的组件可以写一个简单的循环监控脚本发现down了自动提醒。如果保留Prometheus组件GitLab管理后台自带监控图表能直接看到PostgreSQL、Redis、Puma的实时指标对定位内存暴涨、数据库连接数偏高等问题很有帮助。资源紧张时可以关掉但长期运维保留着更安心。5.3 升级节奏与版本追踪GitLab每月都会发新版本但生产环境不建议每个月追着升。我的节奏是关注官方月度更新日志判断有没有当前版本相关的安全修复。如果有安排一次升级如果只是普通功能更新可以等几个小版本积累后再一次升级。每次升级前先确认目标版本和当前版本之间的升级路径避免跨大版本。升级窗口尽量选在凌晨或团队使用低峰期升级过程中GitLab服务不可用是正常现象提前通知团队成员比出问题后再解释强得多。升级之后重新检查一遍备份策略是否仍然生效。这个约定永远不变。最终我在实际维护中最大的体会是安装GitLab这件事本身不难难的是装完之后的日常维护。很多人把功夫花在选系统、敲命令上结果装完一跑就丢在脑后等出问题才手忙脚乱。建议第一次装的时候就把备份脚本、日志检查、磁盘监控一起搭好之后再升级、加用户、跑CI都会轻松很多。最后还有一个容易被忽略的小细节GitLab的配置文件改完之后不一定要每次都执行完整的 reconfigure。很多时候只需要 gitlab-ctl restart 对应的组件就能生效速度和影响范围都小得多。但涉及 external_url、端口映射、数据库这类核心配置时还是要乖乖走完整的 reconfigure避免改了配置但实际没生效带来的困惑。希望这些经验能帮你少踩几个坑装出一台干净、稳定、好维护的GitLab。