手把手教你搭建自己的gitlab以及CI服务(避坑指南)

3,723 阅读10分钟

关键字

linux docker gitlab-ce gitlab ci gitlab-runner

阅读本文前需要先提前了解以上关键字

从本文你能获得什么

  • 搭建自己的gitlab服务的能力
  • 搭建gitlab-ci服务的能力
  • 配合gitlab实现项目自动提交代码并进行项目发布的能力

为什么要搭建自己的gitlab

我们常用的沉淀代码、知识的方法有:

  • 截图保存
  • 书签收藏网页
  • 直接down代码到本地
  • 上github fork
  • 巴拉巴拉

说白了,不爱折腾的技术不是好技术^_^

每个人都会有自己的方法,但是你的资源/代码/工程放在哪里更合适?当然是git库了,在服务器上搭个git server也能实现,但是项目管理功能基本没有。

gitlab闪亮登场,它的功能和优点不这里不做赘述。具体信息请参考 gitlab官网

环境准备

一台电脑windows / mac / Ubuntu 或者其他类linux系统的电脑/服务器都ok。 当然配置得还说得过去,本文示例的系统环境为:阿里云Linux 双核 4G内存

软件安装以及启动

docker的安装和启动

  1. 安装docker: yum install docker
  2. 启动docker: systemctl start docker

从官网获取docker

gitlab-ce的安装和启动

  1. 拉取gitlab-ce镜像文件:docker pull gitlab/gitlab-ce:latest
  2. 启动gitlab-ce:
#!/bin/bash
HOST_NAME=gitlab.aaa.com
GITLAB_DIR=/root/dockerdata/gitlab
docker stop gitlab
docker rm gitlab
docker run -d \
    --hostname ${HOST_NAME} \
    -p 8089:80 \
    --name gitlab \
    -v ${GITLAB_DIR}/config:/etc/gitlab \
    -v ${GITLAB_DIR}/logs:/var/log/gitlab \
    -v ${GITLAB_DIR}/data:/var/opt/gitlab \
    docker.io/gitlab/gitlab-ce:latest

建议将以上启动命令制作为shell脚本,方便修改和服务重启等操作。 还有几点需要注意:

1.1. HOST_NAME: 这里需要制定访问gitlab的具体url,即需要将gitlab.aaa.com替换成你自己的域名

1.2. -p 参数 表示容器和host主机的端口映射关系(可以指定多个),如果指定了端口映射需要服务器上配置好hostname和端口的转发操作,以nginx的配置为例:

server {
    listen 80;
    server_name gitlab.aaa.com 127.0.0.1 localhost;
    client_max_body_size 100M;

    location / {
        proxy_pass http://localhost:8089/;
    }
}

1.3. -v 参数 表示容器路径和host主机文件的映射关系(可以指定多个),如果设置了路径映射则需要保证host主机上文件路径存在

等待容器启动完成,便可以通过指定的域名访问。

关于容器的操作及参数可以在这里得到解答:

docker run 命令

docker 命令大全

3.前端页面登录gitlab:

如果前面一切顺利,那么到这里你就应该能登录到自己的gitlab啦。

but,你有账号吗?

提供两种比较简便的方法:

  • 直接打开gitlab的地址

    初次打开时系统直接提示让你修改密码并确认密码,两次密码校验相同后,回到登录页面,账号:root, 密码:你刚才输入的密码就可以登录了。如下图:

  • 通过输入邮箱获取账号密码 点击密码确认按钮下方的request new one,来到输入邮箱地址的界面,如下图:

当然还有其他方式,待大家探索发现

到这里gitlab的安装就完成了,可以在里面尽快的玩耍(折腾)了

你以为到这里就结束了?目前新建账户、存代码什么的是没问题了,还得带上CI(Continuous Integration,持续集成)功能才好玩。持续集成是什么?说白了就是项目自动构建、上传、发布等这些操作

gitlab ci的安装和启动

gitlab ci只是功能,对应真正的docker 镜像名称叫gitlab-runner

  1. 拉取gitlab-runner镜像文件: docker pull gitlab/gitlab-runner:latest
  2. 启动qitlab-runner:
#!/bin/bash
docker stop gitlab-runner
docker rm gitlab-runner
docker run -d --name gitlab-runner \
    --net host \
    --restart always \
    -v /gitlab/gitlab-runner:/etc/gitlab-runner \
    -v /var/run/docker.sock:/var/run/docker.sock \
    -v /etc/hosts:/etc/hosts \
    -v /root/project:/root/project \
    gitlab/gitlab-runner:latest
  1. 获取注册gitlab-runner的关键参数:

    gitlab-runner分为三种:

  • specific runner:顾名思义,某个项目专享的runner
  • group runner:这个group内的所有项目都可以使用的runner
  • shared runner:所有项目都可以使用的runner

注册runner需要记住两个关键的参数:url令牌

如何创建specific runner

项目主页 -> 左侧菜单设置 -> CI/CD -> Runner 点击展开,如下图所示:

由于我已经注册过一个共享型runner,所有右侧共享runner会显示有一个可用runner. 由于我们是在某个项目的设置里面设置runner,所有通过左侧给定的参数(马赛克部分)创建的runner均为specific runner

如何创建shared runner

管理中心 -> 概览 -> Runner

如下图所示:

通过这两个参数(马赛克部分)创建的runner就是共享型runner,可供所有项目打包发布等操作

找不到“管理中心”?顶部的那个小扳手就是啊

如何创建group runner

项目组 -> 左侧菜单设置 -> CI/CD展开

如下图所示:

三种runner的url和令牌的获取方式都已经知道了,下一步就是注册runner:

4.如何注册runner

4.1. 先进入gitlab-runner 容器内部: docker exec -it 容器id bash

4.2. 执行命令:gitlab-runner register,出现交互式输入:

- Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/):
输入上文中获取的url
- Please enter the gitlab-ci token for this runner:
输入上文中获取的令牌
- Please enter the gitlab-ci description for this runner:
runner的描述,可以所以输入
- Please enter the gitlab-ci tags for this runner (comma separated):
这个输入比较重要,就输入:dev,test,prod (后面会讲到)
- Please enter the executor: shell, virtualbox, custom, docker, docker-ssh, parallels, ssh, docker+machine, docker-ssh+machine, kubernetes:
由于我们的服务是跑在docker里面的,所有输入docker即可
- Please enter the default Docker image (e.g. ruby:2.6):
基础镜像,用于我们的项目构建时指定运行环境,通常会设置为:alpine:latest

如果一切顺利,会看到下面这段话:

Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!

good job!再次回到gitlab,找到runner列表会发现,多了一个runner实例:

如何使用这个runner?

如果你期望在的项目中使用CI功能,需要在项目根目录新增一个:.gitlab-ci.yml的文件,然后在里面做一些配置信息即可,如下是一个极简的示例配置:

dev:
  script:
    - npm install
    - npm run build
    - mkdir -p /root/project/mainPage
    - cp ./dist /root/project/mainPage/ -fr
  tags:
    - dev

这里需要注意:tags里面的值需要和创建runner时输入的tags匹配一个即可,如:dev,test,prod 能匹配dev,表示可以执行CI,否则CI操作将无法被执行。

关于.gitlab-ci.yml的详细配置,点击这里

如果一切顺利,当你给项目提交代码后,就会看到项目已经在进行自动的发布,如下图所示:

当然,一切哪能这么顺呢?

遇(cai)到(guo)的(de)问(keng)题

  1. gitlab的webIDE功能一直都是不可用的状态,如图:

后来跟踪了一下,发现是其请求的几个接口使用的是:group+projectname拼接的接口路径,导致接口404,如果将接口中路径部分的group+projectname替换为项目id即可,已经在gitlab官网上翻过了,有人遇到过同样的问题,没有得到解决,不了了之啊。 点击这里 查看详情

  1. 流水线作业时,提示host无法解析的问题,如下图所示:

这个坑在于,在容器内部通过curl访问是ok的,就以为网络没啥问题,后来经过高人指点说用telnet试试,果然telnet不通。确定是dns解析的问题了,在机器里面设置: nameserver 8.8.8.8即可

  1. 流水线作业时提示403

403 http status code的字面意思是:资源禁止访问。

3.1git库为什么会禁止访问?

runner 服务在拉取git库的代码时也需要指定账号密码才行,在我们没有设置账号密码的前提下,去拉git库当然会被禁止了

3.2如何设置账号密码

找到gitlab-runner 的配置文件config.toml,然后在指定位置添加如下代码:

[runners.ssh]
    host = ""
    port = ""
    user = ""
    password = ""

把上面四个参数的value自己根据实际情况填写上,当然这个user必须是你的git库存在的且有权限访问项目资源的。配置文件修改完成后,runner服务会自动重启,这个时候再运行流水线作业就Ok啦!

  1. 端口绑定冲突问题

启动gitlab-ce容器时,需要指定端口映射。如果在启动参数中指定参数:--net host就会出现端口占用的问题。如果你先启动nginx或者apache(默认他们都会占用80端口),那么gitlab-ce启动时就会提示端口占用问题,如果先启动gitlab-ce那么nginx又会报同样的错,问题就出在容器的启动参数上!

如果存在端口映射且映射的端口不相同时切记不能添加--net host 启动参数

docker容器支持4种端口绑定模式:host/container/none/bridge(默认), 点击这里 查看详情

  1. CI构建完成的项目如何放在服务器指定的位置

碰到的问题是,项目打包完了,然后呢?因为毕竟是在gitlab-runner容器内部执行的。想着只需要在启动gitlab-runner时添加上路径映射即可,发现并不行。查看CI作业的log,如下图:

在进入容器内部后,并没有找到该目录:/builds/study/mainpage/,甚至连/builds根目录也没找到,简直不可思议!

通过gitlab-runner注册一个runner后,就会生成一个config.toml文件,当然注册多个runner还是只有这一个文件,只是里面的配置项增加了而已。

config.toml文件在哪里?

启动gitlab-runner容器时指定的虚拟路径那里,就是这一项:/gitlab/gitlab-runner:/etc/gitlab-runner, 在容器内直接访问/etc/gitlab-runner地址就能找到,容器外部则切换到/gitlab/gitlab-runner就能找到,下面贴出部分内容:

[runners.docker]
    tls_verify = false
    image = "node:latest"
    privileged = false
    disable_entrypoint_overwrite = false
    oom_kill_disable = false
    disable_cache = false
    volumes = ["/root/project:/root/project", "/cache"]
    shm_size = 0

我们只需要关注volumes这个配置项即可,它将作用于runner service容器的虚拟路径映射,而非gitlab-runner 容器本身 理解这句话,非常重要!

如果看过 盗梦空间 应该很好理解,即:梦中梦。我们的项目编辑打包,.gitlab-ci.yml里面脚本的执行都在这一层(第二层容器runner service)。所有我们为了链接最里层容器(runner service)和最外层服务器,必须一层一层建立路径映射关系。

  1. 启动gitlab-runner容器时有如下参数:-v /root/project:/root/project
  2. 配置runner service时有如下配置项:volumes=["/root/project:/root/project",...],注意这段配置是需要手动添加的,默认的值只有 /cache

如果项目编译完成后通过网络传输到别的地方就不存在我上面说的问题了,以上问题仅限于将文件copy到一个指定的目录时需要考虑容器路径映射

尽情玩耍

这一套折腾下来,可以自己导入项目并自动发布了。Happy ✿✿ヽ(°▽°)ノ✿

后记

以上技术都是使用的现有流行的,纯当练手。没想到依然是各种问题,特别是第2、5两个问题,特别花费时间,第5个问题纯靠摸索。整个安装调试过程花费约1周,当然是零碎的时间。Over~~~