资讯详情

自建GitLab完整教程:服务器部署、内存优化与常见故障排查

📅 2026/10/2 7:38:23 | 华诺云谱 👁 阅读
自建GitLab完整教程:服务器部署、内存优化与常见故障排查
第一次在一台裸机上搭GitLab的时候我连续折腾了两晚卡在502页面直接怀疑人生。后来把官方文档翻了个底朝天又把相关的技术社区帖子扫了一遍才理清整个套路。这篇教程我会把从零到能push代码的完整过程都写下来包括硬件怎么规划、Omnibus包和Docker怎么选、初始密码去哪找、跑完reconfigure之后还要配什么以及我踩过的所有坑。无论你是刚接触Linux的新手还是已经被各种史上最详细教程坑过的老手跟着这篇文章走一遍基本能稳稳当当把GitLab仓库跑起来。1. 自建GitLab仓库前先搞清楚这四件事1.1 为什么不用现成的代码托管平台非要自己搭很多团队的第一反应是GitHub、Gitee都能托管代码为什么还要自己在Linux服务器上装一套GitLab我接触过的自建场景主要分三类。第一类是代码敏感。金融、医疗、政企类项目代码根本不允许出内网托管在第三方平台哪怕私有仓库也过不了合规审查所以必须在自己的服务器上部署一套GitLab CE社区版。第二类是团队协作需要深度定制。GitLab本身自带完整的CI/CD能力可以跟Jenkins、Kubernetes、fluxcd之类的工具链深度集成。自建之后你可以随意改域名、加存储、挂载S3备份、对接企业微信或钉钉通知自由度完全在自己手里。第三类是成本问题。代码托管平台对私有仓库数量和协作人数有限制超过一定规模要收费。团队人数多、仓库数量大的时候自建GitLab可能反而更省毕竟它开源绝大多数中小团队用社区版就完全够用。1.2 GitLab CE与EE的差异社区版到底缺了什么安装之前先分清版本否则看文档容易看懵。GitLab官方提供了两个分支CECommunity Edition社区版和EEEnterprise Edition企业版。EE相比CE多了一些高级功能比如多集群管理、安全合规扫描、效能分析等。对大多数中小团队来说CE已经覆盖了日常几乎所有需求无限私有仓库、Issue管理、Merge Request、CI/CD Runner、Wiki、Container Registry这些都是免费的。需要注意的一点是GitLab官网下载页面的默认入口经常会引导你下载EE试用版下载的时候一定看清楚包名。Debian/Ubuntu系的安装包是gitlab-ceRHEL/CentOS系是gitlab-ce别装成了gitlab-ee。EE虽然可以转CE但过程很折腾不如开始就装对。1.3 安装方式怎么选Omnibus包、Docker还是源码编译GitLab官方推荐的安装方式有三种Omnibus一体化安装包、Docker容器、源码编译。源码编译我只说一句GitLab是Ruby on Rails的大型应用依赖极其复杂源码编译需要处理几百个gem包、数据库初始化、前端资源编译没有个一天半天装不完出了问题还很难排。除非你是GitLab的二次开发贡献者否则绝对不要选这条路。Omnibus包是官方打包的一体化安装包把Ruby、PostgreSQL、Redis、Nginx、Puma这些组件全部绑在一起一条命令装完一条命令初始化。这是官方最推荐、也是社区里踩坑最少的方式。Docker方式用容器封装环境隔离性好宿主机只要装好Docker Engine就能跑。它的优点是可以随意指定版本启动新容器升级不污染原环境缺点是数据卷管理和内存限制需要自己多花心思。在后面的章节我会把两种方式都展开讲。1.4 什么场景下不建议自建说句实话GitLab是出了名的内存大户如果团队只有三五个开发者而且没有专职运维我更推荐直接用第三方的免费托管服务。自建一套GitLab意味着你还要维护操作系统补丁、GitLab版本升级、备份恢复、磁盘扩容、邮件服务这些隐性成本经常被忽略。如果你们团队超过10人或者有代码不能出内网的要求或者有强CI/CD集成需求那么自建才有真正的性价比。理解了这些边界条件再往下安装就不容易半途而废。2. 环境准备与硬件规划多少人用决定你配多少内存2.1 官方最低配置与实际体验配置对照GitLab官方文档给了一套硬件参考值但我实际用下来的体感和官方文档有差距。官方说4GB内存可以支撑500人左右的轻度使用这种理论上限看看就行真跑到500人4GB内存的机器早就卡得连登录页都打不开了。我给自己团队做配置规划时一般按这个表来参考团队规模CPU核心数内存磁盘适用场景说明1-20人2核4GB50GB-100GB SSD代码托管为主不常跑CI流水线20-100人4核8GB200GB SSD频繁使用CI/CD Pipeline和Container Registry100人以上8核以上16GB以上500GB以上 SSD高可用、多Runner、大规模构建并发特别提醒一件事GitLab启动后Puma和PostgreSQL常驻内存大约要占掉2GB左右。如果机器内存刚好卡在4GB系统本身还要吃掉一部分很容易触发OOM内存不足导致服务被内核杀掉。所以内存宁多勿少。2.2 系统版本与依赖检查GitLab官方支持的主流Linux发行版包括Ubuntu 20.04 LTS / 22.04 LTSDebian 11 / 12CentOS 7 / 8CentOS 8已经停止维护建议用Rocky Linux或AlmaLinux替代openEuler、麒麟这类国产化系统如果基于CentOS/RHEL架构也可以参照RHEL系的安装步骤操作安装前先确认系统版本和架构cat /etc/os-release uname -mGitLab目前主要提供x86_64和aarch64两种架构的安装包。如果你的服务器是ARM架构比如华为鲲鹏下载的时候要挑选对应的aarch64包别拿到x86_64的包硬装。2.3 域名或IP规划external_url是第一个大坑安装GitLab之前你必须先想清楚一个问题用户最终通过什么地址访问它这个地址就是external_url它可以是http://172.16.1.100也可以是https://gitlab.example.com。很多人忽略了这个规划随便填了一个内网IP结果装完之后要用域名访问又得回炉重造。external_url最好在安装前就确定下来因为GitLab安装完成后会把大量配置写进/etc/gitlab/gitlab.rb还会根据这个URL生成Nginx配置和OAuth回调地址。中途修改虽然可行但要重新跑一遍gitlab-ctl reconfigure而且如果之前已经创建了项目项目的Clone地址会全部变成旧地址非常麻烦。在写external_url的时候有经验的运维都会直接在URL上区分HTTP和HTTPS因为GitLab会根据这个URL自动决定是否生成SSL证书配置。生产环境强烈建议直接用https://开头。3. 使用Omnibus包安装GitLab完整步骤与关键参数3.1 配置软件源国内外网络环境都要知道的技巧Omnibus包可以从GitLab官方仓库下载但国内网络直连官方源的速度很不稳定经常出现下载到一半断流的情况。我一般直接改用国内镜像源速度和稳定性都靠谱得多。以Ubuntu 20.04 LTS为例使用清华镜像源的配置方法是# 安装基础依赖 sudo apt-get update sudo apt-get install -y curl openssh-server ca-certificates tzdata perl # 添加清华镜像源 curl -fsSL https://packages.gitlab.cn/repository/raw/script/setup.sh | sudo bash这里要说明一下国内镜像源的方式不止一种网上还能看到用mirrors.tuna.tsinghua.edu.cn/gitlab-ce的写法但我实测下来packages.gitlab.cn这个国内企业源稳定性和包更新的及时性都更好。如果是CentOS、Rocky Linux这些RHEL系系统需要先配置yum源# 添加GitLab CE源 cat /etc/yum.repos.d/gitlab_gitlab-ce.repo EOF [gitlab-ce] nameGitLab CE Repository baseurlhttps://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el8/ gpgcheck0 enabled1 EOF # 刷新缓存 sudo yum makecache3.2 安装GitLab CE并设置external_url软件源配置好之后安装命令反而是最简单的Ubuntu/Debian系sudo apt update sudo EXTERNAL_URLhttp://gitlab.example.com apt install gitlab-ceRHEL/CentOS系sudo EXTERNAL_URLhttp://gitlab.example.com yum install -y gitlab-ceEXTERNAL_URL环境变量是官方推荐的第一配置方式它会在安装过程中自动写入/etc/gitlab/gitlab.rb。如果你安装的时候忘了设置也完全不用慌装完之后手动编辑配置文件一样能改sudo vi /etc/gitlab/gitlab.rb找到这一行去掉注释并改成你的地址external_url http://gitlab.example.com然后执行配置生效命令sudo gitlab-ctl reconfigure这里要多说一句gitlab-ctl reconfigure是整个安装流程里最关键的步骤它负责把GitLab所有组件PostgreSQL、Redis、Nginx、Puma、Sidekiq等初始化并启动。首次执行时间非常长通常在3到10分钟之间期间终端没什么输出变化千万不要以为是卡死了就CtrlC中断。3.3 安装过程中的常见假死现象我见过太多人卡在这一步。运行reconfigure的时候终端停留在某个Ruby任务半天不动就急不可耐地关掉终端或者重启服务结果下次启动直接乱套。正确的做法是耐心等待同时另开一个终端观察运行状态sudo tail -f /var/log/gitlab/gitlab-rails/production.log或者查看Nginx是否已经开始监听端口sudo netstat -tlnp | grep -E 80|443|8080如果看到Nginx已经监听80或443端口说明web服务已经起来了。这时候再用浏览器访问你设置的external_url应该能看到GitLab的登录页面。3.4 初始密码隐藏了24小时就消失的那个文件这是新手最容易卡住的地方。GitLab首次初始化后root账号的初始密码会被随机生成并写入一个临时文件sudo cat /etc/gitlab/initial_root_password打开这个文件你会看到类似下面的内容# WARNING: This value is valid only for the next 24 hours. # After the first sign in, the password will be automatically changed. Password: xxxxxxxxxxxx初始密码的有效期只有24小时首次登录后系统还会强制要求修改密码。所以安装完一定要第一时间登录把密码改成自己的别等着第二天再处理到时候初始密码过期就只能上控制台重置了。这里顺便提一个应急重置密码的方法如果你真的错过了初始密码也不用慌可以用Rails控制台改sudo gitlab-rails console进入交互界面后输入user User.find_by(username: root) user.password 你的新密码 user.password_confirmation 你的新密码 user.save!输入quit退出控制台重新登录即可。4. 首个仓库落地改密码、关注册、配SSH、传代码4.1 修改root密码并关闭对外开放注册用root账号和初始密码登录GitLab后系统会跳到修改密码页面。这里我建议直接把密码设成一个强密码并找个密码管理器存起来。登录进去之后第一步不是急着创建项目而是先关掉对外开放注册。默认情况下GitLab是允许任何人注册账号的如果你的服务器暴露在公网就会被各种垃圾账号扫到。关闭路径在系统管理区域Admin Area - Settings - Sign-up restrictions把Sign-up enabled的勾选去掉保存即可。4.2 创建项目与群组先建组再建项目GitLab的权限管理模型是群组Group- 子群组Subgroup或者 项目Project。我推荐有多个项目并行时先创建一个群组再在群组下面创建项目。比如可以创建一个名为devops的群组然后在这个群组下创建名为backend-service的项目。群组成员会自动继承群组的权限不用每个项目重复设置一遍成员管理成本非常低。创建项目的时候GitLab会问你要不要用README初始化仓库。如果是空项目可以直接勾选初始化README这样clone下来就有一个默认分支省去手动commit的麻烦。4.3 本机配置SSH KeyPush代码的第一步创建完项目后页面会提示你配置SSH Key这是GitLab最常见的认证方式。在本地电脑上执行ssh-keygen -t ed25519 -C youremailexample.com一路回车生成默认密钥对然后查看公钥cat ~/.ssh/id_ed25519.pub把公钥内容复制粘到GitLab的Preferences - SSH Keys页面。这里强调一点官方现在推荐ed25519算法比老旧的RSA 2048更安全、密钥更短。如果你的机器上没有id_ed25519.pub也可以生成RSA密钥ssh-keygen -t rsa -b 4096 -C youremailexample.comSSH Key配置好之后可以用以下命令测试连通性ssh -T gitgitlab.example.com看到Welcome to GitLab, username!就说明认证已经通了。4.4 用命令行推代码到GitLab仓库配置好SSH后在本地项目目录里执行git init git add . git commit -m initial commit git remote add origin gitgitlab.example.com:devops/backend-service.git git push -u origin main如果你是在已有的项目里操作直接把远程仓库地址改到GitLab就行。这里有个小细节2023年后新创建的GitLab项目默认分支名是main而不是masterpush之前先确认一下本地分支名避免推送时分支对不上又多一次冲突。5. 换条路走用Docker部署GitLab的完整流程与对比5.1 Docker方式相对Omnibus包的优势和劣势Docker方式这几年越来越流行因为它把GitLab的依赖封装在容器里宿主机上不需要装Ruby、PostgreSQL等一堆东西。我用Docker部署GitLab的体感是优点很明显一是升级方便修改image版本号后重新创建容器就行二是排查问题时可以直接进容器操作与宿主机隔离不会搞坏系统环境三是在开发机上临时起一个测试环境特别快。缺点也同样明显一是容器内文件系统是临时的所有数据必须通过volume挂载到宿主机如果不小心删掉容器又没挂好数据卷数据直接归零二是容器和宿主机之间的文件权限问题经常导致GitLab写文件失败。三是GitLab官方对Docker的支持虽然很成熟但某些依赖组件比如外置PostgreSQL、Redis在容器模式下配置要麻烦一些。5.2 docker run部署GitLab的关键参数说明Docker部署GitLab官方镜像的命令大致如下sudo docker run --detach \ --hostname gitlab.example.com \ --publish 8443:443 --publish 8080:80 --publish 2222:22 \ --name gitlab \ --restart always \ --volume /srv/gitlab/config:/etc/gitlab \ --volume /srv/gitlab/logs:/var/log/gitlab \ --volume /srv/gitlab/data:/var/opt/gitlab \ gitlab/gitlab-ce:latest逐个参数解释一下--hostname相当于Omnibus方式里的external_urlGitLab会根据它生成Nginx配置。--publish端口映射。8443:443表示用宿主机的8443端口映射容器的443端口HTTPS8080:80是HTTP端口2222:22是SSH端口。生产环境SSH端口尽量不要映射成22因为宿主机自己的SSH通常占用了22。--volume数据卷挂载。config目录保存GitLab配置logs保存日志data是核心数据目录包括Git仓库、数据库文件、上传文件等。这三个目录必须持久化否则容器一重启全没。创建完成后等待容器初始化sudo docker logs -f gitlab看到gitlab Reconfigured!字样就说明已经初始化完毕了。5.3 Docker方式升级和数据迁移的注意事项Docker方式升级GitLab非常简单很多人最喜欢的就是这一点。升级流程一般是# 备份 docker exec -t gitlab gitlab-backup create # 拉取新版本镜像 docker pull gitlab/gitlab-ce:16.11.0-ce.0 # 停止并删除旧容器 docker stop gitlab docker rm gitlab # 用相同参数创建新容器 docker run ... gitlab/gitlab-ce:16.11.0-ce.0这里建议不要直接使用latest标签GitLab大版本升级比如从15升到16时数据库迁移可能不兼容最好指定确切的小版本号。升级前一定先看官方Upgrade Path文档别跨好几个大版本一步到位那会造成数据库无法迁移的惨案。6. 高频故障与自救清单502、内存告警、启动卡死6.1 502 Whoops刚启动最常见的那页白屏访问GitLab看到502 Whoops, GitLab is taking too much time to respond.是刚安装完最常见的报错。它分两种原因。第一种是reconfigure还没跑完服务没有完全启动。这种情况只需继续等待观察sudu gitlab-ctl status命令的输出直到所有组件都显示run状态即可。第二种是内存不足导致Puma或PostgreSQL起不来。用free -h查看内存情况如果发现内存占用已经超过90%建议先加Swap再启动# 创建4GB的Swap文件 sudo fallocate -l 4G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile echo /swapfile none swap sw 0 0 | sudo tee -a /etc/fstab加了Swap之后重启一下GitLabsudo gitlab-ctl restart6.2 内存被占满调整Puma和Sidekiq参数GitLab默认配置比较激进Puma会尝试把所有可用内存都利用起来。在8GB内存的机器上GitLab跑一段时间后内存占用经常直奔6GB。这时候需要手动限制Puma的worker数量。编辑/etc/gitlab/gitlab.rbpuma[worker_processes] 2 puma[min_threads] 4 puma[max_threads] 8然后执行sudo gitlab-ctl reconfigure。这个值不是越大越好worker太多会被内存拖累太少在高并发下会有明显延迟。我实测4核8GB的机器2个worker加8个线程对10人以内团队完全够用。6.3 邮件发不出去SMTP配置才是重灾区很多团队装好GitLab后发现密码找回邮件、CI通知邮件都发不出去。原因是GitLab默认没有配置SMTP服务器。配置SMTP需要编辑/etc/gitlab/gitlab.rb加入类似下面的内容gitlab_rails[smtp_enable] true gitlab_rails[smtp_address] smtp.example.com gitlab_rails[smtp_port] 465 gitlab_rails[smtp_user_name] noreplyexample.com gitlab_rails[smtp_password] yourpassword gitlab_rails[smtp_domain] example.com gitlab_rails[smtp_authentication] login gitlab_rails[smtp_enable_starttls_auto] true gitlab_rails[smtp_tls] true不同的邮件服务商配置各不相同如果是企业邮箱一般在配置里能找到SMTP参数。配好之后跑gitlab-ctl reconfigure然后在后台发一封测试邮件Admin Area - Settings - 验证SMTP设置。6.4 与Jenkins联动时的权限设置GitLab最常见的联动场景就是和Jenkins做CI/CD。连接时需要在GitLab创建一个Personal Access Token路径在Preferences - Access Tokens。给Token至少勾选api和read_repository权限。Jenkins侧安装GitLab插件后在Manage Jenkins - Configure System - GitLab里填入GitLab地址和Token测试连接显示success就行。这里常遇到的问题是Jenkins服务器访问GitLab的SSH端口没有放通或者Token权限没勾选导致拉代码401。6.5 SSH克隆端口异常默认22端口被抢占如果服务器本身已经把22端口用于SSH登录Docker方式的GitLab容器里SSH服务就无法映射到宿主机的22端口必须映射成其他端口比如前面的2222:22。这时候项目页面上展示的Clone地址是ssh://gitgitlab.example.com:2222/devops/backend-service.git但如果你的DNS或hosts解析有问题clone时依然会连不上。解决办法是在本机~/.ssh/config里加一段配置Host gitlab.example.com Port 2222 User git这样git clone gitgitlab.example.com:devops/backend-service.git就会自动走2222端口不需要每次手写端口。7. 备份恢复与版本升级平时多做一步数据安全一大截7.1 gitlab-backup备份和恢复GitLab仓库最怕的不是服务器宕机而是磁盘损坏或误删。我强烈建议无论环境大小都配置定期备份。Omnibus包自带备份命令sudo gitlab-backup create默认备份文件存放在/var/opt/gitlab/backups/目录文件名格式类似1717012345_2024_05_29_16.10.0_gitlab_backup.tar。恢复备份前先确认新环境GitLab版本与备份时的版本一致或兼容。恢复命令# 停止相关服务避免数据写入 sudo gitlab-ctl stop puma sudo gitlab-ctl stop sidekiq # 恢复备份输入文件名中时间戳和版本部分 sudo gitlab-backup restore BACKUP1717012345_2024_05_29_16.10.0 # 重启服务 sudo gitlab-ctl start这里要特别提醒备份不光是Git仓库本身配置文件/etc/gitlab/gitlab.rb和密钥文件也要一起备份。没有正确的gitlab-secrets.json文件即使恢复了数据库也无法解密仓库里的敏感信息。所以把整个/etc/gitlab目录都纳入备份计划是最稳妥的。7.2 版本升级的正确姿势GitLab升级最忌讳直接跨多个大版本跳官方也不建议这样操作。升级前一定要先看官方Upgrade Path文档确认从当前版本到目标版本的路线图。以16.x为例如果当前是15.11想要升到16.11必须按15.11 - 16.0 - 16.5 - 16.11这样的步骤每个大版本先升到最新的补丁版本再进入下一个大版本。虽然看起来繁琐但能有效避免数据库迁移失败。升级前做好备份然后执行sudo apt update sudo apt install --only-upgrade gitlab-ce或者从官方仓库下载指定版本的安装包用dpkg -i或rpm -Uvh安装。升级完成后记得跑一遍sudo gitlab-ctl reconfigure让新版本配置生效。7.3 日志查看排查问题最锋利的刀GitLab日志分布在多个路径遇到问题别瞎猜直接看日志是最快的方式。以下是我常用的几个# 总览所有服务状态 sudo gitlab-ctl status # Nginx访问日志和错误日志 sudo tail -f /var/log/gitlab/nginx/gitlab_access.log sudo tail -f /var/log/gitlab/nginx/gitlab_error.log # GitLab应用日志看502、权限、认证问题 sudo tail -f /var/log/gitlab/gitlab-rails/production.log # PostgreSQL日志数据库连接异常 sudo tail -f /var/log/gitlab/postgresql/current # Puma日志Ruby进程崩溃 sudo tail -f /var/log/gitlab/puma/current排查的时候养成先查内存、再查日志、最后看网络端口的三步打法90%的问题都能定位到根因。我最后再分享一个小习惯每次装完GitLab我都会新建一个管理员操作记录页面把安装日期、版本号、external_url、备份任务的cron表达式、SMTP配置这几项关键信息都记下来。几个月后再去维护这台服务器时根本不用回忆当初怎么装的直接翻记录就能对上。GitLab这类系统一旦用起来就是长期依赖前期这些细致工作往后会帮大忙。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑