GitLab 是一个主要由 Ruby on Rails 语言开发的开源应用程序,实现一个自托管的 Git 项目仓库,可通过 Web 界面进行访问和管理,简而言之就是一个可以私有化部署的 github.com。
Gitlab 官方实际上已经提供了 N 种安装和部署的方式,有直接通过操作系统软件源进行安装的,也有通过 Docker 方式部署的,甚至有通过源代码方式自行编译安装的(稍复杂)。
那么为什么这里要选择较复杂的方式呢?因为官方目前构建的软件包或者 Docker 镜像都是基于 X86 架构的,并没有对 ARM64v8 的支持。而通过搜索 Docker Hub 是能够找到构建好的支持 ARM64v8 的 Docker 镜像的,但 任 然存在一些瑕疵:
- 该镜像只能跑在 Ubuntu 系的 Linux 发行版上,在 CentOS 上跑则会出错,因为 Gitlab 使用了 redis,redis 默认依赖 jemalloc,jemalloc 在编译时使用到了操作系统内核 pagesize 参数,Ubuntu 系的 pagesize 是 4K,而 CentOS 则是 64K,在 pagesize 低的系统上编译的软件无法在 pagesize 高的系统上运行。
- 即使在 Ubuntu 上能够正常运行,其中个 grafana 组件也会报 Exec format error 错误,这是因为镜像作者在编译时没有注意到其中的 grafana 组件使用的是 X86 的软件包。
基于以上原因,选择自行构建能够在 CentOS 上运行的 Docker 镜像。
1 准备编译环境
编译前需要准备一个编译环境的,里面包含编译过程中所需要用到的工具链。这里选择通过 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 ... 省略 ...
2 编译 Gitlab 安装包
根据 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 。
3 通过 Gitlab 安装包构建镜像
同样,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 .
4 运行 Gitlab Docker 容器
运行 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'

作者:李凌
更多干货尽在【中国信创服务社区】,点击文末左下角“了解更多”即可进入!

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