资讯动态

统信UOS ARM64环境源码编译GitLab CE完整指南

发布时间:2026/10/22 9:14:46 来源:尧图企业网站定制
接到这个需求的时候我第一反应其实是找现成的安装包。GitLab 官方 Omnibus 安装包用起来多省事一条命令装完。可等我看清目标机器的架构是 ARM64、系统是统信UOS 的时候这条路基本断了一半。官方 Omnibus 仓库对 ARM64 的覆盖本来就有限对统信UOS这种发行版更是没有现成的内置包。于是只能老老实实走源码编译的路子在 UOS 上把 GitLab CE 从源码一步步搭起来。这篇文章是我整个过程的实操记录内容包括版本选择、依赖准备、源码编译、数据库初始化、服务启动以及一堆我在 ARM64 环境下反复踩过的坑适合准备在国产化环境里自建代码托管平台的同学参考也给要维护 ARM64 服务器的人避避雷。1. 需求剖析与方案选型1.1 为什么非要用源码方式搭先交代一下背景。这个项目所在的机器是一台 ARM64 架构的服务器操作系统是统信UOS。彼时手头要搭建企业内部代码托管平台既要支持 SSH 克隆又要接 CI 流水线还要能跑项目权限管理GitLab 在这些能力上比较完整所以选型几乎没犹豫。但真正操作起来就发现问题全在安装环节。官方 Omnibus 安装包虽然支持 Debian / Ubuntu 等系统但对统信UOS这种国产发行版并没有内置包对 ARM64 的支持更是有限。有人可能会想那我直接去 GitHub 下载一个通用二进制包不就行了实际操作下来Omnibus 包内部把 Ruby、PostgreSQL、Redis 这些运行时全部打包在了一起而且把路径固定到了/opt/gitlab/embedded这种目录里。在不匹配的发行版上glibc 版本、库文件路径一有差异启动就是一连串的undefined symbol或者cannot open shared object file排查起来非常折磨。源码安装的好处就是完全绕开这种内置运行时的依赖所有组件都跟随你用系统包管理器和源码编译的版本走路径、版本、编译参数都可以自己控制。在统信UOS这种相对小众的环境里这种方式兼容性最好。代价也很明显编译时间长依赖多中间容易出错但一旦跑通后面扩展和定制组件版本也方便。1.2 源码安装相比安装包的取舍我在方案评审的时候列过一张对比表基本可以代表源码安装和 Omnibus 安装的差异对比维度Omnibus 安装包源码安装安装速度快一条命令依赖检查很慢光编译 Assets 可能就要半小时以上对发行版要求严格只支持少数主流发行版宽松只要依赖能装齐就能编路径控制固定/opt/gitlab自己定义如/home/git/gitlab组件版本官方锁定自己选但要匹配 GitLab 依赖要求二次开发不方便改内部代码直接在源码里改改完重新 Rails 启动升级维护官方重建包操作简单需要自己重新走编译流程工作量偏大排障难度内置组件黑盒组件都是系统库和服务排查路径清晰当时的结论很简单既然目标是统信UOS ARM64 这种官方没有预编译包的组合就没什么可纠结的源码安装是唯一能让所有组件版本可控、后续能维护下去的方式。下面进入正题。2. 环境准备与版本规划2.1 确认环境信息动手前先花五分钟把机器环境核对清楚这一步省得后面反复改路径。我在服务器上执行了下面几条命令uname -m # 确认是否为 aarch64 cat /etc/os-release # 确认系统发行版和版本号 lscpu # 确认 CPU 核数和架构 free -h # 确认内存大小 df -h /home # 确认磁盘剩余空间我这边输出的架构是aarch64系统是统信UOS V20内存 16G磁盘剩余 80G。GitLab 源码编译对磁盘和内存的要求都不低磁盘建议至少预留 40G内存建议 8G 以上内存不够的话编译到前端 Assets 阶段大概率会触发 OOM。如果目标机器内存不够至少把 swap 调大我后面在排障章节会专门说。2.2 安装系统依赖统信UOS 社区版基于 Debian 体系包管理器是 apt。如果你的 UOS 版本是服务器版且衍生自 CentOS 体系那把 apt 换成 yum 即可包名可以通过 yum 搜索确认。安装编译工具链和基础依赖库的命令如下sudo apt update sudo apt install -y build-essential \ curl wget rsync \ libssl-dev libkrb5-dev \ libxml2-dev libxslt1-dev \ libicu-dev libpq-dev \ zlib1g-dev libreadline-dev \ libsqlite3-dev \ libssh2-1-dev \ libcurl4-openssl-dev \ pkg-config cmake \ graphviz这里面有一个特别容易忽略的libicu-dev。GitLab 的国际化处理依赖 ICU缺失的话后面编译nokogiri或rugged会直接报错。还有libssh2-1-dev编译rugged需要它。graphviz是生成文档图表用的GitLab 里部分 Rake 任务会调用。2.3 创建专用用户与目录规划GitLab 官方强烈不建议直接用 root 跑。我创建了一个git用户所有服务和代码都装在这个用户下面sudo useradd --create-home --shell /bin/bash git sudo passwd git然后规划目录结构。我采用的是官方手动安装文档推荐的布局方便后续升级和备份/home/git/ ├── gitlab/ # GitLab 主源码目录 ├── gitlab-shell/ # SSH 访问仓库的配套组件 ├── gitaly/ # Git RPC 服务组件 ├── repositories/ # 实际仓库存储目录 └── .gitlab_shell/ # Shell 配置目录这些目录先不急着创建后面每一步用到时再建。源码目录的属主要记得给git用户。很多新手容易在这个环节踩坑后面启动 Rails 时会遇到 permission denied原因全是目录属主不对。3. 核心组件安装与版本匹配3.1 GitLab 与依赖组件的版本对应关系这是整个搭建过程里我最想强调的一点GitLab 的源码安装对组件版本要求很严格Ruby 大版本、Node 大版本、Go 版本、PostgreSQL 版本、Redis 版本都有上下限。不同版本 GitLab 之间的依赖差异很大不要随便拿一个最新版 Ruby 就去编。我这里拿 GitLab CE 14.10 系列为例这是我实际采用的版本组合组件版本要求我实际使用的版本GitLab CE14.10.x14.10.5Ruby2.7.x2.7.5Bundler2.x2.3.11PostgreSQL12.x 或 13.x13.4Redis4.0 以上6.0.16Node.js14.x14.18.2Yarn1.22.x1.22.19Go1.16 ~ 1.171.17.7如果你要用 GitLab 15 或更高的版本Ruby 至少要 3.0Node 要 16Go 要 1.19 以上对应的编译参数和配置文件也可能变化。我的建议是选定一个版本组合后严格按照官方该版本的依赖说明来安装不要混搭。3.2 Ruby 与 Bundler 安装UOS 系统仓库自带的 Ruby 版本通常很低满足不了 GitLab 的要求。我从源码编译的方式安装指定版本的 Rubysudo apt install -y autoconf bison libyaml-dev libgdbm-dev libncurses-dev cd /usr/local/src sudo curl -L -o ruby-2.7.5.tar.gz https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.5.tar.gz sudo tar xzf ruby-2.7.5.tar.gz cd ruby-2.7.5 sudo ./configure --prefix/usr/local/ruby sudo make -j$(nproc) sudo make install编译完成后把路径写进git用户的.bashrcexport PATH/usr/local/ruby/bin:$PATH export GEM_HOME/usr/local/ruby/lib/ruby/gems/2.7.0然后验证ruby -v gem -v bundle -vbundle -v如果提示找不到说明本机还没装 Bundler执行gem install bundler -v 2.3.11即可。这里提醒一句Ruby 源码编译在 ARM64 上比较慢实测大概十分钟左右如果中途报错优先看是不是缺了 libyaml-dev 这类依赖。3.3 Go、Node 与 Yarn 安装GitLab 里负责 Git 操作的核心组件 Gitaly 是用 Go 写的必须装 Go。我从官方下载了 go1.17.7 的 ARM64 包解压到/usr/local/gocd /usr/local sudo curl -L -o go1.17.7.linux-arm64.tar.gz https://go.dev/dl/go1.17.7.linux-arm64.tar.gz sudo tar xzf go1.17.7.linux-arm64.tar.gz export PATH/usr/local/go/bin:$PATH go version前端资源编译需要 Node.js 和 Yarn。因为 GitLab 14 前端构建要求 Node 14所以我装的是 Node 14.18.2curl -L -o node-v14.18.2-linux-arm64.tar.xz https://nodejs.org/dist/v14.18.2/node-v14.18.2-linux-arm64.tar.xz sudo tar xJf node-v14.18.2-linux-arm64.tar.xz -C /usr/local/ export PATH/usr/local/node-v14.18.2-linux-arm64/bin:$PATHYarn 用npm install -g yarn1.22.19安装即可。这里我要特别提醒不要图省事用系统自带的 Node 或者最新版 Node前端依赖里sass等包的编译对 Node ABI 版本敏感Version 不匹配会直接编译失败。3.4 PostgreSQL 与 Redis 准备GitLab 的元数据全部存储在 PostgreSQL 里仓库引用和任务队列依赖 Redis。这一步我更推荐直接用 UOS 仓库里的包省去编译数据库的时间。sudo apt install -y postgresql-13 redis-server sudo systemctl enable --now postgresql sudo systemctl enable --now redis-server然后给 GitLab 创建数据库和用户。GitLab 会要求一个单独的用户不能使用 postgres 超级用户直接跑sudo -u postgres psql -c CREATE USER gitlab CREATEDB; sudo -u postgres psql -c CREATE DATABASE gitlabhq_production OWNER gitlab;Redis 这边有一个关键配置GitLab 通过 unix socket 连接 Redis 在性能上更好但也容易出权限问题。我采用的方案是让 Redis 监听本地 TCP 端口简单直接后面配置gitlab.yml时写redis://127.0.0.1:6379即可。4. 源码编译与配置落地4.1 准备 GitLab 源码和配套组件主源码我直接从 GitLab 官方仓库拉取指定 tagsudo -u git -H git clone --branch v14.10.5 --depth 1 https://gitlab.com/gitlab-org/gitlab.git /home/git/gitlab cd /home/git/gitlab这里建议用--depth 1只拉一个 tag不要全量 clone否则历史提交会占掉很多磁盘空间和时间。拉完代码后还要准备两个配套组件gitlab-shell和gitaly。它们和 GitLab 主版本有严格对应关系特别是 Gitaly 的版本必须跟主版本匹配sudo -u git -H git clone --branch v14.10.5 --depth 1 https://gitlab.com/gitlab-org/gitlab-shell.git /home/git/gitlab-shell sudo -u git -H git clone --branch v14.10.5 --depth 1 https://gitlab.com/gitlab-org/gitaly.git /home/git/gitaly配置文件的起点是官方自带的模板。在/home/git/gitlab下cd /home/git/gitlab sudo -u git cp config/gitlab.yml.example config/gitlab.yml编辑gitlab.yml里的核心配置项重点包括host、port、repositories路径以及gitlab-shell的secret_token。secret_token要在/home/git/gitlab-shell下单独生成并复制到主配置中sudo -u git -H /home/git/gitlab-shell/bin/install这条命令会自动生成secret_token并完成 shell 组件的初始化。如果没有执行这一步后面通过 SSH 访问仓库时会报 key 验证失败。4.2 后端依赖安装踩坑实录GitLab 主目录下执行 bundle 安装cd /home/git/gitlab sudo -u git -H bundle install --without development test --jobs 4这个过程在 ARM64 上会经历大量 native extension 编译比如nokogiri、json、rugged、bcrypt、eventmachine等。我实际遇到的两个高频报错第一个是nokogiri编译失败提示找不到 libxml2 或 libxslt。原因是系统里虽然装了基础库但缺少开发头文件。解决方式就是回到 2.2 节把libxml2-dev libxslt1-dev libicu-dev装齐。第二个是rugged编译失败它依赖 libgit2而且需要 libssh2 支持。只装libssh2-1-dev还不够有时候还会提示libssh2.h找不到此时可以用sudo apt install -y libssh2-1-dev libgit2-dev装完后不需要清理整个 bundle直接重跑一次bundle install即可已编译成功的 gem 会被缓存。这里还要补充一个我踩了很久的坑不要在 root 下执行bundle install。GitLab 的很多文件属主要和运行用户一致如果你用 root 装了 bundle后面切换成git用户跑 Rails 时会遇到Gem::FilePermissionError到时候再 chown 一堆目录会很麻烦。4.3 前端资源编译后端依赖装完之后开始编译前端静态资源。命令如下cd /home/git/gitlab sudo -u git -H yarn install --frozen-lockfile sudo -u git -H bundle exec rake assets:precompile RAILS_ENVproduction NODE_ENVproduction这一步是耗时最长的环节在 ARM64 上实测接近四十分钟期间 CPU 会长时间满载风扇起飞属于正常现象。我的建议是不要全程盯着屏幕改用后台执行并把日志写入文件sudo -u git -H nohup bundle exec rake assets:precompile RAILS_ENVproduction NODE_ENVproduction /tmp/assets.log 21 tail -f /tmp/assets.log如果日志里出现Command failed或者Sass::CompilationFailed原因通常是系统缺少graphviz或者内存不足导致node子进程被杀。前者安装 graphviz 包即可后者就要参考排障章节调整 swap。4.4 Gitaly、Puma 与 Sidekiq 配置Gitaly 是 GitLab 内部所有 Git 操作的实际执行者源码装好后需要单独编译cd /home/git/gitaly sudo -u git -H make allGitaly 的配置在/home/git/gitaly/config.toml。我使用的是最简单的socket模式socket_path /home/git/gitaly/gitaly.sock token your-secret-token [storage] name default path /home/git/repositories这个 token 要和gitlab.yml里 gitaly 相关的token保持一致不然 Rails 和 Gitaly 之间握手失败页面会一直转圈。Puma 的配置在config/puma.rb源码包自带模板直接复制sudo -u git cp config/puma.rb.example config/puma.rb模板默认绑定tcp://127.0.0.1:8080端口冲突可以改。我建议把 worker 数调低一点在 2~4 之间ARM64 机器上太高的话内存很容易吃紧。Sidekiq 是 GitLab 的异步任务队列启动命令可以在源码自带的lib/support目录下找 service 模板也可以直接用下面的方式启动cd /home/git/gitlab sudo -u git -H nohup bundle exec sidekiq -e production -C config/sidekiq.yml /tmp/sidekiq.log 21 5. 初始化数据库与启动联调5.1 初始化数据库在启动服务之前要先让 Rails 读取配置文件并初始化数据库结构cd /home/git/gitlab sudo -u git -H bundle exec rake db:create RAILS_ENVproduction sudo -u git -H bundle exec rake db:migrate RAILS_ENVproduction sudo -u git -H bundle exec rake gitlab:setup RAILS_ENVproductionrake db:create会根据gitlab.yml里的数据库配置连接 PostgreSQL。如果创建失败八成是 3.4 节里创建的数据库用户和密码没有正确写入config/database.yml。这一步执行完后控制台会输出 GitLab 的初始管理员账号一般是rootlocal.host系统会提示你设置密码。如果忘记设置可以用sudo -u git -H bundle exec rails console -e production u User.find(1) u.password 新密码 u.password_confirmation 新密码 u.save! exit这种方式重置管理员密码比直接改数据库要安全Rails 会自动做密码哈希和验证规则处理。5.2 服务启动顺序与维护命令源码安装模式下没有gitlab-ctl这种统一管理命令所以必须手动控制服务启动顺序。我推荐的顺序是RedisPostgreSQLGitalySidekiqPumaGitLab Workhorse前两个由 systemd 管理直接systemctl start即可。Gitaly 需要在/home/git/gitaly目录下编译并启动cd /home/git/gitaly sudo -u git -H nohup ./gitaly config.toml /tmp/gitaly.log 21 GitLab Workhorse 是反向代理负责把 HTTP 请求转发给 Puma 和 Gitaly。它的源码在/home/git/gitlab/workhorse子目录下编译并启动cd /home/git/gitlab/workhorse sudo -u git -H make build sudo -u git -H nohup ./gitlab-workhorse -listenNetwork tcp -listenAddr 127.0.0.1:8181 -authBackend http://127.0.0.1:8080 /tmp/workhorse.log 21 最后启动 Pumacd /home/git/gitlab sudo -u git -H nohup bundle exec puma -C config/puma.rb -e production /tmp/puma.log 21 这里要注意源码安装里 Puma 默认监听 8080Workhorse 监听 8181如果你只想访问原始 Rails 端口可以直接用http://服务器IP:8080。但我建议把 Nginx 或 Workhorse 放在前面做入口这样静态资源处理和 SSH 转发都更自然。5.3 功能验证清单服务起来之后我按下面的清单验证验证项验证方式预期结果Puma 存活curl -I http://127.0.0.1:8080返回 HTTP 302页面入口浏览器访问http://服务器IP:8080显示 GitLab 登录页注册登录使用 root 登录能进入管理后台SSH 验证ssh -T git服务器IP提示 Welcome to GitLab仓库创建新建项目并初始化 README能显示文件列表仓库克隆git clone git服务器IP:/project.git能正常克隆提交推送修改文件并 push页面能刷新出提交记录CI 检查项目里创建.gitlab-ci.yml并启用 RunnerPipeline 能创建任务其中 SSH 验证这一步非常关键。如果提示Permission denied (publickey)先确认用户的公钥已经添加到 GitLab 的 SSH Keys 里再看gitlab-shell的authorized_keys配置是否正确。源码安装模式下authorized_keys一般是git用户下的~/.ssh/authorized_keys要注意目录权限必须是 700文件权限必须是 600。6. 常见问题速查与避坑技巧6.1 ARM64 编译问题在 ARM64 环境里最普遍的问题是某些 gem 没有预编译的 ARM64 版本必须现场编译但现场编译经常缺依赖。这里把所有高频问题汇总成一张表症状可能原因处置方法nokogiri编译失败缺少 libxml2/libxslt 开发头文件安装libxml2-dev libxslt1-devrugged编译失败缺少 libssh2/libgit2安装libssh2-1-dev libgit2-deveventmachine编译失败缺少libssl-dev安装libssl-dev后重新 bundleGitalygo build拉取依赖失败Go module 下载受限提前在能访问软件源的环境里下载依赖或用内网 Go module 缓存Assets 编译时 node OOM内存不足调整 swap 或减少 Yarn 并发关于 Go module 依赖我要多说一句Gitaly 的依赖很多离线环境下非常痛苦。最稳妥的方式是在有网络的环境中先把 Gitaly 仓库 clone 下来然后执行go mod vendor把依赖打进 vendor 目录再把整个目录拷到目标机上。这样后续就算目标机器不能访问外部的 Go module 源也能正常编译。6.2 运行时与运维问题症状可能原因处置方法页面 502 Gateway TimeoutPuma 没起来或 Workhorse 转发失败查/tmp/puma.log/tmp/workhorse.log页面一直加载Gitaly rpc 超时Gitaly 没启动或 token 不一致检查 Gitaly 进程和gitlab.ymltoken创建仓库失败repositories目录属主不是 git 用户执行chown -R git:git /home/git/repositoriesSidekiq 队列积压Sidekiq 进程退出查看/tmp/sidekiq.log确认 Redis 连接SSH 克隆提示无法连接gitlab-shell 初始化失败重新执行bin/install确认secret_token源码安装没有统一的进程守护进程很容易在服务器重启后丢失。我给所有服务都写了 systemd 单元文件这里贴一个 Sidekiq 的示例[Unit] DescriptionGitLab Sidekiq Afternetwork.target redis-server.service postgresql.service [Service] Usergit WorkingDirectory/home/git/gitlab ExecStart/usr/local/ruby/bin/bundle exec sidekiq -e production -C config/sidekiq.yml Restartalways [Install] WantedBymulti-user.targetPuma、Gitaly、Workhorse 都可以按同样的思路写成 systemd 服务这样重启机器后服务能自动拉起不再需要手动 nohup。6.3 关于内存与 swap 的调整建议整个搭建过程中内存是我遇到的最大瓶颈。16G 内存的机器编译前端资源时node进程经常被 OOM Killer 干掉现象就是assets:precompile跑到一半没有任何报错就退出查看/var/log/kern.log才发现进程被杀了。解决办法是增加 swap。对 ARM64 开发机来说swap 分区大小可以设为内存的 1~2 倍。我用一个 swap 文件解决sudo fallocate -l 16G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile写进/etc/fstab后重启也会自动挂载。这个操作对编译大项目非常有用不只是 GitLab编译 Chromium 或大体积 Node 工程时都能用上。结尾算上配置、编译和排障我在统信UOS ARM64 环境里前前后后折腾了三天才把 GitLab 完整跑起来。最大的感受是这东西不是靠一条命令装完就结束而是要把每个组件都当成一个独立服务去对待。源码安装虽然累但它逼着你去理解 GitLab 内部的组件关系后面做二次开发、做容灾备份心里都是有底的。最后再分享一个小技巧源码装完 GitLab 后先别急着设置一堆复杂配置应该立刻打一个完整的/home/git目录快照。这样后续如果再调试坏可以直接把快照解压回来省去重新编译几小时的等待。我在项目里就是靠这个快照后来升级测试时把系统环境备份了一遍整个过程顺畅了很多。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑