Docker Compose 部署 GitLab 和 GitLab-Runner

上一篇文章里提到了在整理我的个人文件的时候,有一些项目相关的琐碎文件需要有备份和版本控制,最好的方式就是使用现成的工具 Git。

我之前一直是直接在 VPS 上面初始化空代码库,从个人电脑上直接同步。这样的好处是只要有一台云主机就行,不需要任何配置,坏处也显而易见,在那台主机上到底托管了多少代码库无法一目了然。交互也只有命令行一种方式。因为刚好有一台 2c8g,只用来搭梯子和 host Hexo 站点,几乎算是一直闲置。资源足够,所以打算花点时间折腾一下,部署一套 GitLab 并且可以使用它原生的 CI/CD。

根据我折腾主机的经验,与其花时间去安装各种依赖,解决各种奇怪问题,不如直接用 Docker。容器化的服务对新手更加友好,维护起来也比较方便。就算哪里折腾坏了,停下容器,删掉镜像,就可以假装什么都没有发生过。Docker 命令行比较复杂,所幸现在有了 docker-compose 这样的工具,可以在一个 yaml 文件里面配置好所有的服务。指定各个容器使用的镜像、映射的端口和挂载本机硬盘的路径。

使用 Docker 部署 GitLab 的教程网上有一大把,官方的文档也很详细。按文档操作毫无难度,唯一需要注意的一点就是 GitLab 需要一段时间启动,在启动的时候,docker ps 命令会显示 starting,此时是无法正常访问页面的。我个人遇到的另外一个问题是没有看到初次登录时重置 root 用户密码的界面。解决方案是直接在 VPS 上进入挂载到容器的硬盘路径里,在 GitLab 的 config 路径下直接查阅原始密码,复制粘贴出来完成初次登录。后续的操作就都可以在 UI 上进行。因为这个实例不出意外的话只有我一个用户,所以也就没有配置 SMTP 来发邮件,也没有开放用户注册(除了给自己注册了一个管理员帐户日常使用)。

GitLab 原生支持 CI/CD,但是需要接入 GitLab-Runner。后者也可以使用容器部署在同一台云服务器上,按官方文档操作即可。这里有一个点需要注意,如果 runner 的容器和 GitLab 的容器不在一个 docker network 内,是无法互相通信的。也就是说,runner 无法联系到 GitLab 实例,也就无法完成注册。解决办法是把 runner 和 GitLab 放到同一个 network 里,在 docker-compose.yml 里面为两个容器指定同一个 network 即可。这个 network 可以任意起名,使用默认的 bridge driver 就可以。容器之间通信使用的不是域名,而是容器名,为了在注册 Runner 到 GitLab 的时候可以正常使用域名,可以在 docker-compose.yml 里面 GitLab 的 network 字段把域名设置成这个容器的别名。

其实到这里就可以把这个 runner 实例注册为 GitLab 的跨代码库通用 runner 了,在 UI 上也可以看到 GitLab 和 Runner 之间可以正常通信,CI/CD 的 Job 也可以正常跑起来。但是,我遇到了另一个问题。我把 runner 的执行环境设置为了 docker,CI Job 在初始化 runner 上的容器环境之后,应该从 GitLab 里拉下代码库,并执行我设定好的命令。可是却因为无法和 GitLab 代码库通信,最终超时报错。

这是因为执行器根据 CI 的配置文件里写的镜像生成的容器已经不再是 GitLab-runner 那个容器了。CI Job 的执行容器是新生成的,它默认不在 GitLab 所在的 network 里,所以无法拉下代码。根据前面配置 runner 的经验,我们只需要设置执行器在创建容器时默认使用和 GitLab 相同的网络,理论上就可以解决问题了。经过一番搜索,我发现这个配置项在 Runner 的配置文件里。可以通过在 VPS 上进入挂载到 runner 容器的目录里,找到 config.toml 在里面直接修改来实现。具体就是配置 network-mode 为 GitLab 容器所在的网络名称。

所以在写这篇文章的时候,我的 GitLab 实例已经正常运行了两天了。我另一个 Hexo 的站点,也终于不需要依赖电脑来生成静态网页了。因为 GitLab Runner 和 Hexo 在同一个节点,我直接把 nginx 的网页根目录所在的路径挂载给了 runner 容器。这样在我更新 hexo 的 master branch 的时候,CI 会在 runner 上实例化一个有 node.js 的容器,执行安装 Hexo 并且生成静态网页的命令。之后就可以直接把 public 文件夹下的所有文件拷贝到挂载到容器的 nginx 网页根目录完成部署。全过程大约 20 秒(除了第一次 pull image 需要花点时间)。

我的个人简历使用 LaTex 制作的,之前更新简历都离不开我的电脑,电脑上有 LaTex 的二进制文件和编译环境。现在只要更新简历的 master branch,CI 就会使用 LaTex 的镜像为我编译简历,并且把 PDF 输出到 GitLab 的 artifacts,保留一个月。整个过程不到 10 秒。我可以用手机、用 iPad,随时随地更新自己的简历和 Hexo 站点了。

在需要和朋友交流代码的时候,拥有这么一个 GitLab 站点也是十分方便。接下来有时间了,可以研究一下怎么给它配置 https 证书。高位端口,目前也没有使用 nginx 反代,可能实现起来还要费一番功夫。

很开心拥有自己的 GitLab 实例,写下此文以示庆祝!