GitLab 是一个主要由 Ruby on Rails 语言开发的开源应用程序,实现一个自托管的 Git 项目仓库,可通过 Web 界面进行访问和管理,简而言之就是一个可以私有化部署的 github.com。

Gitlab 官方实际上已经提供了 N 种安装和部署的方式,有直接通过操作系统软件源进行安装的,也有通过 Docker 方式部署的,甚至有通过源代码方式自行编译安装的(稍复杂)。

那么为什么这里要选择较复杂的方式呢?因为官方目前构建的软件包或者 Docker 镜像都是基于 X86 架构的,并没有对 ARM64v8 的支持。而通过搜索 Docker Hub 是能够找到构建好的支持 ARM64v8 的 Docker 镜像的,但 任 然存在一些瑕疵:

  1. 该镜像只能跑在 Ubuntu 系的 Linux 发行版上,在 CentOS 上跑则会出错,因为 Gitlab 使用了 redis,redis 默认依赖 jemalloc,jemalloc 在编译时使用到了操作系统内核 pagesize 参数,Ubuntu 系的 pagesize 是 4K,而 CentOS 则是 64K,在 pagesize 低的系统上编译的软件无法在 pagesize 高的系统上运行。
  2. 即使在 Ubuntu 上能够正常运行,其中个 grafana 组件也会报 Exec format error 错误,这是因为镜像作者在编译时没有注意到其中的 grafana 组件使用的是 X86 的软件包。

基于以上原因,选择自行构建能够在 CentOS 上运行的 Docker 镜像。

编译前需要准备一个编译环境的,里面包含编译过程中所需要用到的工具链。这里选择通过 Docker 容器方式来构建编译环境,因为用完即可丢弃,不影响 Host 操作系统的环境。并且官方提供了 Dockerfile,构建起来非常方便:gitlab-omnibus-builder。以 Ubuntu 18.04 为例,官方提供的 Dockerfile 在这里,需要注意的是其中有两处地方使用了 X86 架构的软件包,需要改为 ARM64 版本的,关键之处如下:

 FROM ubuntu:bionic as builder     ...     省略     ... # 下面这里的 go 版本应由 amd64 改为 arm64RUN curl -fsSL "{GO_VERSION}.linux-amd64.tar.gz" \  | tar -xzC /usr/local \  && ln -sf /usr/local/go/bin/go /usr/local/go/bin/gofmt /usr/local/go/bin/godoc /usr/local/bin/     ...     省略     ... # 下面这里的 node 版本应由 x64 改为 arm64RUN curl -fsSL "{NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.gz" \  | tar --strip-components 1 -xzC /usr/local/ \  && node --version     ...     省略     ...  

根据 Docker Hub 上第三方 ARM64 版 Gitlab 镜像(gitlab-ce-arm64v8)作者提供的构建脚本,发现他在 Gitlab 官方提供的编译脚本上作了几处针对 ARM64 架构的修改,再整合上面提到的遗漏的 grafana 问题,得出的最终编译步骤如下:

 # 首先运行一个构建环境镜像,其中挂载了一个目录是为了方便将编译好的包拷贝出来:docker run -it --name gitlab-build -v /output/:/output/ -d gitlab_builder_arm64 # 进入镜像内部并进入 output 目录:docker exec -it gitlab-build /bin/bashcd /output # 拉取 Gitlab 源代码,这里指定了版本 12.9.7+ce.0:git clone --depth=1 -b 12.9.7+ce.0  # 进入代码目录并开始安装 Ruby 的依赖包cd ./omnibus-gitlab/ALTERNATIVE_SOURCES=true bundle install --path .bundle --binstubs # 修改几处针对 ARM64 架构的地方:sed -i "s/\.\/configure/\.\/configure --build=arm-linux/" config/software/ncurses.rbsed -i "s/\#{arch}/arm64/" config/software/grafana.rb# grafana 还需要修改对应的文件 hash,否则会校验不过,无法编译:sed -i "s/0104bfe14444cea2fa3f021b9a75fc78f66434f2ca8f3d0bdd422d108ce682e7/86ead48d7f1f4a5ec04b2d5544425a9d7657c731e66d3722b5a301ddb60f4923/" config/software/grafana.rb # 正式编译:ALTERNATIVE_SOURCES=true COMPILE_ASSETS=true bin/omnibus build --log-level=info gitlab# 编译时间较长,并且由于网络等因素,可能会出错,只能根据报错信息应对解决。# 小提示:如果编译途中有部分较大的软件包屡次下载失败的话,可以从别的地方下好拷进软件包临时目录,位于:/var/cache/omnibus/cache  

编译完成后,在 pkg 目录下会生成一个 deb 安装包: gitlab-ce_12.9.7-ce.0_arm64.deb

同样,Gitlab 官方在源码仓库的 docker 目录下提供了 构建 Gitlab docker 镜像的 Dockerfile,但是其中有一个文件 RELEASE 没有说明清楚,通过查询资料得知里面存放了一些用到的变量,具体如下:

 PACKAGECLOUD_REPO=gitlab-ceRELEASE_PACKAGE=gitlab-ceRELEASE_VERSION=12.9.7-ce.0DOWNLOAD_URL=  

DOWNLOAD_URL 是存放 Gitlab 的 deb 安装包的地方,也就是上面步骤中构建好的。后面构建 Docker 镜像时会下载这个包,其实本来打算去掉这个下载步骤,直接将包拷贝到镜像容器里面,安装完再删除的,但是这样会使得镜像体积增大,因为增加了一个镜像的 layer,因此还是临时搭了一个 nginx 放包下载。

此外,还需要修改的几处地方,最终整个构架步骤如下:

 git clone --depth=1 -b 12.9.7+ce.0  ./omnibus-gitlab/dockerecho "PACKAGECLOUD_REPO=gitlab-ce" > RELEASEecho "RELEASE_PACKAGE=gitlab-ce" >> RELEASEecho "RELEASE_VERSION=12.9.7-ce.0" >> RELEASEecho "DOWNLOAD_URL=#34; >> RELEASEsed -i "s/16\.04/18\.04/" ./Dockerfile  # 升级为 ubuntu 18.04 版本sed -i "s/\-\-header\s.*\s.*\s//" assets/download-package  # 去掉 access token,因为 nginx 没有这方面限制 # 构建 Gitlab Docker 镜像:docker build -t gitlab-ce_ubuntu_18.04_arm64 .  

运行 Gitlab 容器官方也提供了 N 种方案,这里不再赘述,仅复制一个通过 docker-compose 启动的最简单的例子:

 web:  image: 'gitlab-ce_ubuntu_18.04_arm64'  restart: always  hostname: 'gitlab.example.com'  environment:    GITLAB_OMNIBUS_CONFIG: |      external_url '#39;      # Add any other gitlab.rb configuration here, each on its own line  ports:    - '80:80'    - '443:443'    - '22:22'  volumes:    - '/docker-data/gitlab/config:/etc/gitlab'    - '/docker-data/gitlab/logs:/var/log/gitlab'    - '/docker-data/gitlab/data:/var/opt/gitlab'  

欢迎大家关注“湖南长城科技”头条号,一起学习网信产业信息技术创新应用知识,了解网信产业动态!