1. 为什么选择自建 GitLab 而不是用云端托管
很多团队一开始图省事,代码仓库直接扔在第三方托管平台上,用着用着就发现不对劲:项目数量一多,私有仓库的协作席位费用蹭蹭往上涨;CI/CD 的构建分钟数稍微跑几个大项目就见底;更别提某些场景下代码资产必须留在自己机房里的硬性要求。这时候,自建 GitLab 就成了一个绕不开的选项。
GitLab 社区版(CE)是开源免费的,功能覆盖了代码托管、代码审查、Issue 跟踪、CI/CD 流水线、制品仓库、容器镜像仓库等一整条研发链路。说白了,它不只是一个放代码的地方,而是一个完整的 DevOps 平台。你把它搭起来,团队从提交代码到自动构建、自动部署,整条链路都能在一个系统里闭环。
那为什么标题里特别强调 CentOS 7.6?因为这套组合在实际生产环境里出现频率极高。CentOS 7 系列在企业内网服务器上装机量巨大,7.6 又是一个相对成熟稳定的版本节点,很多公司的存量机器就是跑的这个系统。而 GitLab 官方对 CentOS 7 的支持也持续了很长时间,两者搭配属于“经典组合”。但经典归经典,坑一点都不少——从安装源的选择、依赖包的冲突,到内存占用、端口配置、邮件服务,每一步都可能让你卡上半天。
这篇内容适合谁看?如果你手里有一台 CentOS 7.6 的服务器,想从零把 GitLab 搭起来并跑通基本使用流程,那这篇就是给你写的。我会把每一步背后的逻辑讲清楚,把容易踩的坑提前标出来,让你少走弯路。整个过程我会用一台模拟的内网服务器来演示,配置是 4 核 CPU、8GB 内存、100GB 系统盘,这个配置对中小团队来说是比较现实的起点。
2. 安装前的环境准备与方案选型
2.1 硬件配置到底要多少才够用
GitLab 是出了名的“吃内存”。很多人第一次装完发现访问特别慢,甚至直接 502,八成是内存不够。这里给一个基于实际经验的配置参考:
| 使用规模 | CPU | 内存 | 磁盘 | 说明 |
|---|---|---|---|---|
| 个人测试 | 2 核 | 4GB | 50GB | 勉强能跑,但开启 CI 后会很吃力 |
| 小团队(10人内) | 4 核 | 8GB | 100GB | 比较舒服的起点,推荐 |
| 中型团队(30人内) | 8 核 | 16GB | 200GB+ | 需要配合外部数据库和对象存储 |
| 大型团队 | 16 核+ | 32GB+ | 按需扩展 | 建议拆分为多节点架构 |
为什么内存这么关键?GitLab 内部由多个组件构成:主应用是 Ruby on Rails,跑在 Puma 上;后台任务用 Sidekiq 处理;还有 PostgreSQL 数据库、Redis 缓存、Nginx 反向代理、Gitaly 代码存储服务等等。这些组件每一个都要占内存,加起来 4GB 是底线,8GB 才能算宽裕。
提示:如果你的服务器内存只有 4GB,务必在安装后创建 swap 分区,否则一旦内存打满,系统会直接杀掉 GitLab 的进程,表现为服务莫名其妙挂掉。
2.2 系统层面的初始化操作
拿到一台干净的 CentOS 7.6 之后,别急着装 GitLab,先把系统基础环境理顺。这几步看着简单,但跳过任何一步后面都可能出问题。
第一步,更新系统并安装常用工具:
yum update -y yum install -y curl policycoreutils-python openssh-server perl vim wget net-tools这里policycoreutils-python是给 SELinux 用的,openssh-server保证 SSH 可用,perl是 GitLab 某些脚本依赖的。别小看这些依赖,缺了它们安装脚本可能中途报错。
第二步,处理防火墙。CentOS 7 默认用的是 firewalld,你需要放行 HTTP、HTTPS 和 SSH:
systemctl start firewalld systemctl enable firewalld firewall-cmd --permanent --add-service=http firewall-cmd --permanent --add-service=https firewall-cmd --permanent --add-service=ssh firewall-cmd --reload如果你打算用自定义端口(比如 8080),那就把--add-service换成--add-port=8080/tcp。
第三步,处理 SELinux。这一步是重灾区。SELinux 默认是 enforcing 模式,它会拦截 GitLab 的很多文件操作和网络绑定,导致各种莫名其妙的权限错误。有两种处理方式:
- 直接关闭:修改
/etc/selinux/config,把SELINUX=enforcing改成SELINUX=disabled,然后重启。 - 保持开启但调整策略:这种方式更安全,但配置复杂,需要针对 GitLab 的各个目录设置上下文。
对于大多数自建场景,我个人的建议是直接关闭 SELinux,因为 GitLab 的官方安装包对 SELinux 的适配并不完美,排查 SELinux 导致的权限问题非常耗时。关闭之后重启系统生效。
第四步,设置主机名。GitLab 会用主机名生成一些内部链接,如果主机名是默认的localhost,后面访问可能出问题:
hostnamectl set-hostname gitlab.internal同时在/etc/hosts里加上一条解析记录,把主机名指向本机 IP。
2.3 安装源的选择与网络考量
GitLab 官方提供了多种安装方式:源码编译、Docker 镜像、Omnibus 包。对于 CentOS 7.6 上的生产部署,我强烈推荐用 Omnibus 包,也就是官方打包好的 rpm 安装包。原因很简单:它把 GitLab 需要的所有组件(PostgreSQL、Redis、Nginx 等)都打包在一起,安装和升级都是一条命令的事,省去了大量手动配置依赖的工作。
安装源有两种获取方式:
- 官方源:通过脚本自动添加仓库配置。
- 手动下载 rpm 包:适合内网环境,先把包下载好再传到服务器上。
如果你的服务器能直连外网,用官方脚本最省事:
curl -sS https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh | sudo bash但很多内网服务器是隔离的,这时候就得手动下载。你可以在一台能上网的机器上,从官方仓库找到对应 el7 版本的 rpm 包,下载后通过内网传输工具传到目标服务器。注意要选el7结尾的包,因为 CentOS 7.6 对应的就是 el7。
注意:不要随便用第三方源或者来路不明的镜像包,GitLab 的安装包体积大、组件多,被篡改的风险不低。认准官方渠道。
3. 安装过程与核心配置实操
3.1 执行安装与首次配置
环境准备好之后,安装本身其实很快。如果用官方源,直接:
EXTERNAL_URL="http://gitlab.internal" yum install -y gitlab-ce这里的EXTERNAL_URL很关键,它决定了 GitLab 生成的各种链接地址。如果你后面想改,需要修改配置文件并重新配置。所以一开始就想清楚:是用 IP 访问,还是用域名访问?如果是域名,DNS 要提前解析好。
如果用手动下载的 rpm 包:
rpm -ivh gitlab-ce-<版本号>-el7.x86_64.rpm安装完成后,不要急着启动,先改配置文件。GitLab 的主配置文件是/etc/gitlab/gitlab.rb。这个文件内容非常多,但初期你只需要关注几个关键项:
external_url 'http://gitlab.internal' gitlab_rails['time_zone'] = 'Asia/Shanghai' gitlab_rails['smtp_enable'] = true gitlab_rails['smtp_address'] = "smtp.example.com" gitlab_rails['smtp_port'] = 465 gitlab_rails['smtp_user_name'] = "gitlab@example.com" gitlab_rails['smtp_password'] = "your_password" gitlab_rails['smtp_domain'] = "example.com" gitlab_rails['smtp_tls'] = true gitlab_rails['gitlab_email_from'] = "gitlab@example.com"external_url是访问地址,time_zone设成中国时区,否则提交记录的时间会让你困惑。SMTP 配置是为了让 GitLab 能发邮件——注册确认、密码重置、合并请求通知都依赖它。如果不配邮件,用户注册后收不到确认邮件就登录不了。
改完配置后,执行重新配置命令:
gitlab-ctl reconfigure这个命令会读取gitlab.rb,生成各个组件的实际配置,并启动所有服务。第一次执行会比较慢,可能要几分钟,耐心等它跑完。跑完之后,用gitlab-ctl status检查各组件状态,正常情况下应该都是run。
3.2 内存优化与组件裁剪
8GB 内存的机器跑默认配置,时间长了可能会有点紧张。GitLab 允许你关掉一些用不上的组件来省内存。比如你如果不用内置的监控(Prometheus、Grafana 那一套),可以在配置文件里关掉:
prometheus_monitoring['enable'] = false grafana['enable'] = false alertmanager['enable'] = false这几个组件加起来能吃掉 1GB 以上的内存,关掉之后对中小团队来说完全没影响,因为你可以用外部监控系统。
另外,Puma 的 worker 数量也可以调。默认是根据 CPU 核数自动算的,4 核机器可能会开 4 个 worker,每个占几百 MB。如果内存紧张,可以手动限制:
puma['worker_processes'] = 2还有 Sidekiq,后台任务处理器,也可以限制并发:
sidekiq['max_concurrency'] = 10这些调整的核心逻辑就是:用并发能力换内存空间。对十几人的小团队来说,并发需求本来就不高,牺牲一点并发换取稳定性是划算的。
3.3 首次登录与管理员初始化
GitLab 安装配置完成后,浏览器访问你设置的external_url,会看到登录页面。初始管理员账号是root,密码在哪里?GitLab 会把初始密码写到一个临时文件里:
cat /etc/gitlab/initial_root_password这个文件在首次重新配置后 24 小时会被自动删除,所以拿到密码后第一件事就是登录进去改掉。登录之后,进入管理区域,把一些基础设置调好:
- 关闭公开注册:
Settings -> General -> Sign-up restrictions,取消Sign-up enabled。自建 GitLab 通常只给内部人用,开放注册会带来安全风险。 - 设置默认分支保护:确保主分支不会被随意强推。
- 配置用户和群组:按团队结构建好群组,把项目归到对应群组下,方便权限管理。
提示:如果你在浏览器访问时遇到 502,先别慌。等一两分钟再刷新,因为 GitLab 首次启动时各组件需要时间预热。如果持续 502,用
gitlab-ctl status看哪个组件没起来,再用gitlab-ctl tail <组件名>看日志。
4. 日常使用中的高频操作与避坑经验
4.1 代码推送与 SSH 密钥配置
GitLab 跑起来之后,最常用的操作就是推拉代码。用 HTTP 方式推代码每次都要输账号密码,很烦。正确姿势是配置 SSH 密钥。
在本地机器上生成密钥对(如果还没有的话):
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"然后把公钥(~/.ssh/id_rsa.pub)的内容复制出来,在 GitLab 的Settings -> SSH Keys页面粘贴进去。之后用 SSH 地址克隆和推送就不需要密码了。
这里有个常见的坑:如果你改了 GitLab 的 SSH 端口(默认 22,但有时会和系统 SSH 冲突),克隆地址里的端口号要写对。比如你把 GitLab 的 SSH 端口改成了 2222,那克隆地址应该是:
git clone ssh://git@gitlab.internal:2222/group/project.git而不是默认的git@gitlab.internal:group/project.git。这个细节不注意,会一直提示连接被拒绝。
4.2 备份策略与恢复演练
自建 GitLab 最不能省的一步就是备份。代码资产丢了,那真是哭都来不及。GitLab 自带备份命令:
gitlab-backup create这个命令会备份数据库、仓库、上传文件等,生成一个 tar 包放在/var/opt/gitlab/backups/目录下。但注意,它不会备份配置文件(/etc/gitlab/gitlab.rb和/etc/gitlab/gitlab-secrets.json)。这两个文件必须单独备份,尤其是gitlab-secrets.json,里面存了数据库加密密钥,丢了的话恢复出来的数据很多是解不开的。
完整的备份策略应该是:
- 定期执行
gitlab-backup create,把生成的包传到异地存储。 - 单独备份
/etc/gitlab/整个目录。 - 定期做恢复演练,确保备份真的能用。
恢复的步骤也不复杂,但顺序要对:
# 先停掉相关服务 gitlab-ctl stop puma gitlab-ctl stop sidekiq # 恢复备份包(把 <timestamp> 换成实际的时间戳) gitlab-backup restore BACKUP=<timestamp> # 恢复配置文件 # 把之前备份的 gitlab.rb 和 gitlab-secrets.json 放回 /etc/gitlab/ # 重新配置并启动 gitlab-ctl reconfigure gitlab-ctl restart注意:恢复操作会覆盖现有数据,一定要在测试环境先演练一遍,确认流程没问题再在生产环境操作。
4.3 常见故障排查速查表
实际运维中遇到的问题五花八门,这里整理几个高频故障和排查思路:
| 现象 | 可能原因 | 排查方法 | 解决方式 |
|---|---|---|---|
| 访问 502 | 内存不足或组件未启动 | gitlab-ctl status、free -h | 加内存或关组件、加 swap |
| 推送代码报权限错误 | SSH 密钥未配置或端口不对 | 检查~/.ssh/config和克隆地址 | 重新配置密钥、修正端口 |
| 收不到邮件 | SMTP 配置错误 | gitlab-rails console里测试发信 | 检查 SMTP 参数、端口、加密方式 |
| 页面加载极慢 | 磁盘 IO 瓶颈或内存不足 | iostat、top | 换 SSD、优化内存配置 |
| 升级后无法访问 | 数据库迁移未完成 | gitlab-ctl tail看日志 | 等待迁移完成或回滚 |
排查 GitLab 问题的核心工具是gitlab-ctl tail,它能实时输出所有组件的日志。遇到问题先看日志,大部分错误信息都很明确,比瞎猜高效得多。
4.4 版本升级的正确姿势
GitLab 的版本升级有个铁律:不能跨大版本升级。比如你从 14.x 想升到 16.x,不能一步到位,必须沿着升级路径一步步来:14.x -> 15.x -> 16.x,每个大版本内还要按官方推荐的路径走。
升级前必须做的几件事:
- 完整备份,包括配置文件和备份包。
- 查看官方升级路径文档,确认当前版本到目标版本的推荐路径。
- 在测试环境先升一遍,确认没问题再动生产。
升级命令本身很简单:
yum install -y gitlab-ce-<目标版本> gitlab-ctl reconfigure但升级过程中的数据库迁移可能耗时较长,期间服务不可用。所以一定要选在业务低峰期操作,并提前通知团队。
5. 性能调优与长期维护心得
5.1 磁盘空间管理与清理
GitLab 用久了,磁盘空间会被各种东西吃掉:Git 仓库本身、CI 构建产物、容器镜像、日志文件、备份包。100GB 的盘,如果不管,可能半年就满了。
几个清理方向:
- CI/CD 构建产物:在项目设置里配置构建产物的过期时间,比如 7 天自动清理。
- 容器镜像仓库:定期清理不再使用的镜像标签,可以配置清理策略。
- 日志文件:GitLab 的日志默认会轮转,但如果你发现
/var/log/gitlab占用过大,可以调整轮转策略。 - 备份包:本地保留最近几份即可,历史备份传到异地后删掉本地副本。
可以用du -sh /var/opt/gitlab/*快速定位哪个目录占用最大。
5.2 监控告警的搭建思路
自建服务最怕的就是“挂了没人知道”。GitLab 本身提供了一些健康检查接口,比如/health和/-/readiness,可以用外部监控工具定期探测。
我个人的做法是用一个轻量的监控脚本,定时检查 GitLab 的 HTTP 状态码和关键进程,异常时通过邮件或内部通讯工具告警。核心监控项包括:
- HTTP 访问是否正常(状态码 200)
gitlab-ctl status各组件是否都在运行- 磁盘使用率是否超过阈值(比如 80%)
- 内存使用率是否持续过高
这些检查不需要多复杂的工具,一个 shell 脚本加定时任务就能搞定。关键是告警要能真正触达到人,否则监控形同虚设。
5.3 安全加固的几个实用动作
自建 GitLab 暴露在内网,虽然不像公网那么危险,但基本的安全加固还是要做:
- 强制 HTTPS:如果条件允许,配置 SSL 证书,让所有访问走 HTTPS。可以用内部 CA 签发的证书,或者用免费证书。
- 限制注册:关闭公开注册,新用户由管理员手动创建或通过 LDAP 同步。
- 定期更新:GitLab 会不定期发布安全补丁,关注官方公告,及时升级。
- 访问日志审计:定期检查登录日志和操作日志,发现异常及时处理。
- 双因素认证:对管理员账号开启 2FA,多一层保护。
这些措施看着琐碎,但真出事的时候,每一条都可能帮你挡住一次风险。
5.4 我踩过的几个印象深刻的坑
说几个我自己实际踩过的坑,都是文档里不太会写、但实际很容易遇到的。
第一个坑是主机名解析。有一次装完 GitLab,本机访问正常,但同网段其他机器访问就各种跳转错误。查了半天发现是/etc/hosts里主机名没配好,GitLab 生成的链接指向了一个外部解析不了的地址。后来把主机名和 IP 的映射在所有相关机器的 hosts 文件里都加上,问题解决。
第二个坑是备份恢复时的版本一致性。有一次用旧版本的备份包往新版本 GitLab 上恢复,结果数据库结构对不上,恢复失败。后来才明白,备份和恢复的 GitLab 版本必须一致,跨版本恢复要先恢复到对应版本再升级。
第三个坑是CI Runner 的并发配置。默认情况下,一个 Runner 可能同时跑多个构建任务,如果服务器资源不够,构建任务之间会互相抢资源,导致全部变慢甚至失败。后来在 Runner 配置里限制了并发数,问题才稳定下来。
这些经验归结起来就一句话:GitLab 的坑大多不在安装本身,而在配置细节和长期运维上。装起来只是开始,把它用稳、用好,需要持续的关注和调整。
6. 从零到跑通:一个完整的实操流程回顾
把整个流程串一遍,方便你对照操作。假设你拿到一台全新的 CentOS 7.6 服务器,配置 4 核 8GB,内网 IP 是 192.168.1.100,计划用gitlab.internal作为访问域名。
第一步,系统初始化。更新系统、装依赖、关 SELinux、配防火墙、设主机名和 hosts 解析。这几步做完,重启一次系统,确保所有设置生效。
第二步,添加 GitLab 安装源。能上网就用官方脚本,不能上网就手动下载 rpm 包传上去。
第三步,安装 GitLab。用EXTERNAL_URL指定访问地址,执行安装命令。
第四步,修改配置文件。设置external_url、时区、SMTP,根据内存情况关掉不必要的组件。
第五步,执行gitlab-ctl reconfigure,等待配置完成。
第六步,获取初始密码,登录后台,修改密码,关闭公开注册,创建用户和群组。
第七步,配置 SSH 密钥,测试代码推送。
第八步,配置备份策略,做一次完整备份和恢复演练。
第九步,搭建基础监控,确保服务异常时能及时发现。
这九步走完,一个可用的 GitLab 环境就搭好了。整个过程如果顺利,半天时间足够;如果踩坑,可能要多花一两天。但把坑踩明白之后,后面维护就轻松多了。
最后分享一个我个人的习惯:每次对 GitLab 做重大变更(升级、改配置、迁移)之前,一定先做一次完整备份,并且在测试环境验证变更方案。这个习惯帮我避免了好几次可能的生产事故。自建服务,稳字当头,慢一点没关系,别把数据搞丢才是底线。