我原来使用的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 down
并up
。
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
,请参考下面的解决方案:
发表回复/Leave a Reply