基于Docker的GitLab配置

我原来使用的Git托管软件是Gogs,近期我迁移到了GitLab。GitLab除了Git托管之外,还包括CI/CD,Registry,Pages等一系列功能。Omnibus Installer使GitLab的安装和配置简化了很多,但是要使用更多的功能,仍然需要手工配置一些服务。

本文记述了使用Docker部署GitLab后开启CI/CD,Registry,Pages等功能的步骤和配置。

硬件需求

官方给出的硬件需求是1Core CPU+ 512MB RAM + 1.5GB SWAP是运行GitLab的最低要求。我使用的是Digital Ocean的5$/月的1C1G实例,开启了4G的Swap。

GitLab本体

Omnibus包包含了GitLab依赖一系列的软件和组件,如ruby, rails, Sidekiq, PostgreSQL等。在Docker中,这些服务都运行在同一个容器中。容器中已经包含了nginx,无需手动配置nginx反向代理。使用如下的compose文件启动GitLab。

web:
  image: 'gitlab/gitlab-ce:latest'
  restart: always
  hostname: 'git.example.com.'
  environment:
    GITLAB_OMNIBUS_CONFIG: |
      external_url 'https://git.example.com'
  ports:
    - '80:80'
    - '443:443'
    - '22:22'
  volumes:
    - './data/config:/etc/gitlab'
    - './data/logs:/var/log/gitlab'
    - './data/data:/var/opt/gitlab'

external_url参数被设置为以https://打头时,GitLab默认使用Let’s Encrypt签发证书。当http及https被暴露到标准端口时,Let’s Encrypt会通过http challenge方式执行自动签发。

当容器启动后,GitLab的基本功能就可以使用了。

GitLab Runner

官方文档: Install GitLab Runner | GitLab

GitLab安装完成后,CI/CD已经默认启用,但是所有构建均会保持在stuck状态,因为GitLab实例还没有注册任何可用的Runner,即GitLab CI的构建执行器。

Runner不包含在omnibus安装包中,需要单独安装。Runner不需要和GitLab实例安装在同一服务器上。

配置

官方文档: Registering Runners | GitLab

首先我们需要注册一个Runner,使其生成配置文件。使用管理员账号登录GitLab实例,在https://your.gitlab.instance/admin/runners中获得实例URL和注册令牌。

在用于安装Runner的服务器上执行下面的命令,在这期间GitLab实例需要保持开启。

 docker run --rm -t -i -v ./runner/config:/etc/gitlab-runner gitlab/gitlab-runner register

系统会弹出下面几个问题:

  • gitlab-ci coordinator URL:在Runner配置页面获得的GitLab实例URL
  • gitlab-ci token:在Runner配置页面获得的注册令牌
  • description for this runner:填写对于此Runner的描述,稍后可以在Runner配置界面更改。
  • tags for this runner:对于此Runner的标签,标签可以用于指定哪些构建可以被分配到此Runner上。
  • runner executer:我们选择docker方式。每种executer的比较见: Executors | GitLab
  • Docker image:当.gitlab-ci.yml中没有指定基础镜像时默认使用的镜像,我使用ubuntu。

运行

完成后,在compose文件中添加如下内容,然后docker-compose downup

runner:
  image: gitlab/gitlab-runner:latest
  volumes:
    - './runner/config:/etc/gitlab-runner'			# 配置文件目录
    - '/var/run/docker.sock:/var/run/docker.sock'	# 宿主机的Docker Socket

Docker Registry

官方文档:GitLab Container Registry administration | GitLab

我们有两种方案来部署Registry。

使用与GitLab实例相同的域名,不同的端口

在gitlab.rb中修改下面一行即可。1234端口可以自己任意设置,但是需要避开5000和5001以避免冲突,同时记得在compose文件中暴露相应的端口。

registry_external_url 'https://gitlab.example.com:1234'

使用与GitLab实例不同的域名,相同的端口

在gitlab.rb中修改如下一行。

registry_external_url 'https://registry.gitlab.example.com'

我在使用自动签发时遇到了问题,所以我选择自己使用acme.sh签发证书。签发完成后将证书及私钥文件拷贝到gitlab配置目录,或直接通过Docker数据卷挂载。

如果你试图将acme.sh签发的证书通过Docker挂载,由于acme.sh签发的证书路径中带有星号,Docker Compose在识别路径时会出现问题。因此我建议将整个.acme.sh目录挂载进容器(如果你没有保护其他非GitLab证书的需求),而不是挂载路径中带有星号的证书文件。

如果证书文件名和域名不相同,需要修改gitlab.rb

registry_nginx['ssl_certificate'] = "/etc/gitlab/ssl/certificate.pem"
registry_nginx['ssl_certificate_key'] = "/etc/gitlab/ssl/certificate.key"

GitLab CI

使用GitLab CI构建Docker镜像

在基于Docker Executor的Runner上构建Docker镜像,Runner需要运行在特权模式(Privileged Mode)。在Runner的config.toml中,将privileged改为true以开启特权模式。

GitLab CI Token

在Pipeline中登录GitLab自带的Container Registry时,当以gitlab-ci-token用户登录时,密码将自动以环境变量$CI_JOB_TOKEN被传入,无需设置额外的环境变量。

.gitlab-ci.yml

image: docker:stable

services:
 - docker:dind

variables:
 CONTAINER_IMAGE: registry.example.cn/$CI_PROJECT_PATH

before_script:
 - docker info

build:
 stage: build
 script:
   - docker build -t $CONTAINER_IMAGE:$CI_COMMIT_REF_NAME .
   - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN registry.example.cn
   - docker push $CONTAINER_IMAGE:$CI_COMMIT_REF_NAME

GitLab Pages

官方文档: GitLab Pages administration | GitLab

GitLab Pages和我们平时使用的GitHub Pages有一些不同,GitHub Pages直接托管git仓库中的静态HTML网站,而GitLab Pages则依赖于GitLab CI将git仓库中的代码(可以是纯HTML,也可以是Hexo或Jekyll项目)通过Pipeline构建后托管。

条件

使用GitHub需要如下条件:

  • 一个独有一级域名,不能使用你的GitLab实例的子域名。
  • 配置DNS泛解析记录
  • (可选)配置通配符(wildcard)SSL证书
  • (可选)配置一个Shared Runner用于构建

配置

修改gitlab.rb,即可启用Pages。

pages_external_url 'https://example.io'

Let’s Encrypt自动签发不适用于GitLab Pages,因此我们使用acme.sh自行签发一个通配符SSL证书,并修改配置。

pages_nginx['redirect_http_to_https'] = true
pages_nginx['ssl_certificate'] = "/etc/gitlab/ssl/pages-nginx.crt"
pages_nginx['ssl_certificate_key'] = "/etc/gitlab/ssl/pages-nginx.key"

完成后执行reconfigure

使用

我们可以通过克隆一个示例项目(如https://gitlab.com/pages/jekyll)来熟悉GitLab Pages的使用。

当仓库被更新时,GitLab CI将按照流水线执行构建,并将生成的静态HTML文件输出到/public

如果构建成功,即可通过https://username.yourgitlab.io/project访问。

TroubleShooting

如果Pipeline执行成功,但是访问Pages页面时报出502错误,同时日志中出现running the daemon as unprivileged user,请参考下面的解决方案:

https://gitlab.com/gitlab-org/gitlab-pages/issues/129

Show CommentsClose Comments

Leave a comment