本文概要和目录
机器有了,docker基础环境用了,现在我们来用docker 部署 gitlab 并且以一个标准的前端工程实战 一个 CICD 流程
安装Gitlab
安装gitlab是我们的重中之重
- 从docker 拉下来
docker pull gitlab/gitlab-ce
复制代码
- 配置它
$ sudo docker run --detach \
--hostname gitlab.example.com \ # 设置主机名或域名 注意⚠️ 这个地方最好设置成你的内网Ip哈
--publish 443:443 --publish 80:80 --publish 22:22 \ # 本地端口的映射
--name gitlab \ # gitlab-ce 的镜像运行成为一个容器,这里是对容器的命名
--restart always \ # 设置重启方式,always 代表一直开启,服务器开机后也会自动开启的
--volume /srv/gitlab/config:/etc/gitlab \ # 将 gitlab 的配置文件目录映射到 /srv/gitlab/config 目录中
--volume /srv/gitlab/logs:/var/log/gitlab \ # 将 gitlab 的log文件目录映射到 /srv/gitlab/logs 目录中
--volume /srv/gitlab/data:/var/opt/gitlab \ # 将 gitlab 的数据文件目录映射到 /srv/gitlab/data 目录中
gitlab/gitlab-ce:latest # 需要运行的镜像
# 443:443:将http:443映射到外部端口443
# 9000:80:将web:80映射到外部端口9000
# 22:22:将ssh:22映射到外部端口22
# 最终我调整好的
docker run -d --hostname 192.168.1.5 -p 443:443 -p 80:80 -p 233:233 --name gitlab --restart always -v/srv/gitlab/config:/etc/gitlab -v /srv/gitlab/logs:/var/log/gitlab -v /src/gitlab/data:/var/opt/gitlab docker.io/gitlab/gitlab-ce
复制代码
除此之外你还需要去更改配置 ,要不然你的git仓库的地址就是默认的git@gitlab.example.com://xxx , 但是正确的地址应该是你自己的ip地址, 设置的方式也非常的简单
# 先修改ssh地址
# 还记得我们之前的地址吗 -v /home/gitlab/config: /etc/gitlab 现在你去到 ,修改rb
$ vim /home/gitlab/config/gitlab.rb
gitlab_rails['gitlab_ssh_host'] = '192.168.52.129' 改成你自己的ip地址
++++
# 改完之后要进入容器 bash重启 这个容器里的gitlab应用
$ docker exec -it gitlab /bin/bash
$ gitlab-ctl reconfigure
$ gitlab-ctl restart
# 再修改http地址
$ vim /home/gitlab/data/gitlab-rails/etc/gitlab.yml
host: 192.168.52.129
# 改完之后要进入容器 bash重启 这个容器里的gitlab应用
docker exec -it gitlab /bin/bash
gitlab-ctl restart
复制代码
- 关于密码
gitlab启动之后,在这里可以看到root的密码,记得登录之后去修改密码哈,我们有一个简单的命令可以查看(因为我们是docker安装的所以比较简单,如果不是docker安装的同学,你需要找别的方法哈)
$ sudo docker exec -it gitlab grep 'Password:' /etc/gitlab/initial_root_password
复制代码
# 当你作完上面的操作之后,
# 运行下面的命令 当你能看到gitlab容器的时候,就意味着你的容器跑起来了,接下来去输入的宿主机的ip就能通过web访问了
root@joney-N8xEJEK:~# docker ps
asCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
989f74cd9bbc gitlab/gitlab-ce:latest "/assets/wrapper" 4 weeks ago Up 7 days (healthy) 0.0.0.0:80->80/tcp, :::80->80/tcp, 22/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp gitlab
root@joney-N8xEJEK:~#
复制代码
GitlabCI
万事具备之后,接下来我们来做CI 流程 (基于GitlabCI),这里是最简单的实现,还有很多功能没有实现在后续的文章中我们会一点点的优化。本文实现的功能如下(GitlabCI + docker + React + 飞书群机器人)
首先我们来介绍一下GitlabCI
所谓的CI 就是自动化 构建,指的是你写完代码之后,提交到仓库,触发了某个事件,然后接下来服务器会自动的去构建你的程序,CD指的是你在你自动构建了程序之后的自动发布操作
概念讲解
- 我们可以通过配置项目下不同的 .gitlab-ci.yml 文件 来,实现不同项目的不同CI流程,它大概长这个样子
stages: # 分段
- package
- install
- lint
- build
- deploy
cache: # 缓存
paths:
- node_modules
- build
- gitlab_test_ci.tar
package-job: # job1
tags:
- hot
only:
- develop
- release
- master
stage: package
script:
- npm config set registry https://registry.npm.taobao.org/
install-job: # job2
tags:
- hot
only:
- develop
- release
- master
stage: install
script:
- npm install
lint-job: # job3
tags:
- hot
only:
- develop
- release
- master
stage: lint
script:
- npm run prettier-format
- npm run lint
复制代码
- Pipeline & Job,Pipeline是Gitlab根据项目的.gitlab-ci.yml文件执行的流程,它由许多个任务节点组成, 而这些Pipeline上的每一个任务节点,都是一个独立的Job
Job在YML中的配置我们将会在下面介绍,现在需要知道的是:每个Job都会配置一个stage属性,来表示这个Job所处的阶段。
一个Pipleline有若干个stage,每个stage上有至少一个 Job,如下图所示:
- 谁去运行我们这些job 呢?
当我们了解上述的基础概之后,我们来思考一个问题,谁负责去完成我们这些工作呢?答案揭晓,负责这些工作是一个小的程序,它就是gitlab-runner,专门为gitlab-ci而生,在这个程序上可以运行很多job。当然了它一般上需要经过一些配置才能使用 ,具体如何使用请见下文。
Runner可以分为两种: Specific Runne (左边的) 和 Shared Runner (右边的)
Shared Runner是Gitlab平台提供的免费使用的runner程序,它由Google云平台提供支持,每个开发团队有十几个。对于公共开源项目是免费使用的,如果是私人项目则有每月2000分钟的CI时间上限。
Specific Runner是我们自定义的,在自己选择的机器上运行的runner程序,gitlab给我们提供了一个叫gitlab-runner的命令行软件,只要在对应机器上下载安装这个软件,并且运行gitlab-runner register命令,然后输入从gitlab-ci交互界面获取的token进行注册, 就可以在自己的机器上远程运行pipeline程序了。
Shared Runner 和 Specific Runner的区别
Shared Runner是所有项目都可以使用的,而Specific Runner只能针对特定项目运行
Shared Runner默认基于docker运行,没有提前装配的执行pipeline的环境,例如node等。而Specific Runner你可以自由选择平台,可以是各种类型的机器,如Linux/Windows等,并在上面装配必需的运行环境,当然也可以选择Docker/K8s等
私人项目使用Shared Runner受运行时间的限制,而Specific Runner的使用则是完全自由的。
Executor 概念
什么是Executor? 我们上面说过 Specific Runner是在我们自己选择的平台上执行的,这个平台就是我们现在说到的“Executor”,为了简单起见,我们没有选择docker 而是选择了shell。我把官方文档的对比图也一并贴出来,供大家参考和选择 适合自己的
参考链接:docs.gitlab.com/runner/exec…
- .gitlab-ci.yml 基础的知识扫盲. 以便于你更快的上手
在正式开始之前我希望你对下面的概念有一定的理解 ,gitlab-runner 就是依据 .gitlab-ci.yml 文件一步一步去执行的
stages:
- package # 这些和1.处的标记一一对应 表示要进行哪些阶段
- lint
- build
- deploy
cache: # 缓存设置
paths:
- node_modules
- build
- gitlab_test_ci.tar
package-job: # job1
tags: # tag标记,你要在那个指定的tag上去运行你的runner,大白话:你要把这个job丢到那个tag表示的runner中运行
- hot
only: # 标记这个job 上在那个分支上有效
- develop
- release
- master
stage: package # 1. 处标记,表示这个job的 stages 到底是什么
script: # 你所要执行的shell命令
- npm config set registry https://registry.npm.taobao.org/
#....下面还有更多的job 但是大多数情况下 就是这样的 结构
复制代码
实战操作
好了,现在让我们从github上拉取 一个既有仓库,来完成CI的配置和运行,(这个github仓库是我自己的初始化的一个React-Ts基础结构包含了lint 和commit 和eslint 以及peptic,至于这个是如何构建的我们这里不关心,我们会开另一个文章来介绍它)。接下来我们准备其他的材料
- 首先 我们有了一个 github的一个react模板 ,它包含了一些基础的功能.
- 我们搭建好了自己的gitlab ,现在我们把这个react模板上次到自己的gitlab仓库 中去 .
- 为我们仓库配置好runner .
- 开始编写.gitlab-ci.yml .
- 进行调试好运行 .
- 拉取先有一个react-ts模板 ,并且 上传到自己的gitlab仓库.
$ git clone https://github.com/BM-laoli/react-ts-template
$ cd react-ts-template
$ git checkout react-tpl
# 这一步执行之前,你需要在自己的gitlab建立一个仓库
$ git remote add org http://192.168.1.5/bigfe/ci-react-pc-test.git
$ git checkout -b develop
# 拉取一个develop 分支来搞
$ git push org develop
复制代码
- 配置runner
下载runner,这里我并没有把runner 丢到docker中,直接放了宿主机,主要原因是docker上跑runner 然后 如果涉及再去build docker image和对宿主机的操作交互十分的麻烦(本人比较的蔡。搞了一个多礼拜没有什么结果,然后放弃了),果断把runner 跑在宿主机中
# Linux x86-64
$ sudo curl -L --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64
$ sudo chmod +x /usr/local/bin/gitlab-runner
$ sudo gitlab-runner install --working-directory=/home/gitlab-runner
$ sudo gitlab-runner start
复制代码
配置它,首先我们我们打开 gitlab上面的项目 ,依据图示找到它
然后?的几个参数很重要
$ sudo gitlab-runner register
# 然后 依据命令行就来.... 至于所要填写的参数都在上面的图中能够找到, 特别需要说明的就 是 tag 我们这里先随意写一个就叫hot
# 完成上面的操作之后,输入下面的命令进行执行
$ sudo gitlab-runner verify --delete
# 这个时候你可直接进入runner 进行观察,看看哪些job在跑,哪些job失败了,失败原因是什么。我这里遇到一个bug 就是piple一直没动静,跑不动,再我run 进runner之后,它就好了。
$ sudo gitlab-runner run
复制代码
按照上面的操作一番之后,我们来到gitlab 如果显示的绿色就说明ojbk了,我们来搞定下面的任务
- 编写.gitlab-ci.yml
每个项目都有不同的部署要求,所以yml也并不是一成不变的,我这里是按照下面的场景设计实现的
主要是两个大的阶段,最后使用node 把build的静态文件 访问打开
阶段1 前端框架的打包:
首先先给ci安装nodejs环境好设置npm镜像,然后下载node_modules,而后 使用代码格式化lint 进行格式验证 ,再然后使用前端的ci工具,build 一下把静态文件打包出来;
阶段2 把静态文件cv到docker image中
使用node启动一个静态资源服务 供外部访问:使用Dockerfile把静态文件 cv到一个装有nodejs 环境的docker image中。
最后把容器run 起来,并且完善 容器的更新和 自动重启升级
.gitlab-ci.yml
# @format
# 执行前配置环境 【package】
# node_module install 【install】
# 检查husky ,代码格式化 ,检查eslint 【lint】
# docker (容器包,这里指的是node下的一个ngx类似的?它就是我们) 【docker】
# run docker ( 走一个 执行docker 文件 )【rundocker】
# 需要给定一些变量控制ci/cd的执行 但这里就先没写了
stages: # 分段
- package
- install
- lint
- build
- deploy
cache: # 缓存
paths:
- node_modules
- build
- gitlab_test_ci.tar
package-job:
tags:
- hot
only:
- develop
- release
- master
stage: package
script:
- npm config set registry https://registry.npm.taobao.org/
install-job:
tags:
- hot
only:
- develop
- release
- master
stage: install
script:
- npm install
lint-job:
tags:
- hot
only:
- develop
- release
- master
stage: lint
script:
- npm run prettier-format
- npm run lint
build-job:
tags:
- hot
only:
- develop
- release
- master
stage: build
script:
- npm run build
# 给定一个 path 的到一个build 目录
# 由于gitlab的CI 默认会delete job的产物,所以这里我们使用cache来缓存一部分内容
# 供后续的job 使用
deploy-job: # 这里的操作主要就是 在runner中拿到build发送到远端服务器,然后在远端服务器 进行docker image的构建操作
tags:
- hot
only:
- develop
- release
- master
stage: deploy
script:
- docker image build -t gitlab-runner-ci-test .
# 先停止运行的容器 然后 马上更新这个容器 使用 shell脚本去运行
- sshpass -p "your-password" chmod 777 build.sh
- ./build.sh
# 这里你可以根据你自己的实际情况去更改 到底是部署到dev 还是 pre 或者是 prd 环境,在我司,这里还会有一个 preBuld.sh 脚本去 构建本地环境,注入api地址,这样就做到了 环境可配置功能
# deploy-job: # 这里的操作主要就是 在runner中拿到build发送到远端服务器,然后在远端服务器 进行docker image的构建操作
# tags:
# - hot
# stage: deploy
# only:
# - master
# script:
# - docker image build -t gitlab-runner-ci-test .
# # 先停止运行的容器 然后 马上更新这个容器 使用 shell脚本去运行
# - sshpass -p "your-password" chmod 777 build.sh
# - ./build.sh
复制代码
dockerfile
# 获取node环境
# 获取npm
# 获取serve
# cv build文件
# 执行run 命令
# ssh 容器跑起来
FROM node:alpine
COPY ./build /app
WORKDIR /app
RUN npm config set registry https://registry.npm.taobao.org
RUN npm install serve -g
CMD ["serve", ".", "-p", "3002"]
EXPOSE 3002
复制代码
build.sh
这里说明一下为什么还需要脚本,主要原因是docker容器更新的时候为了减少体积消耗 和 container 重复 container冲突等问题, 也是依据它我们才能完成 image的重启和版本迭代
#!/bin/bash
##############################################################
# 如果 container 不存在就创建 如果存在就update
##############################################################
docker stop gin-gotest
docker container rm -f $( docker ps -aq --no-trunc --filter name=gin-gotest)
if [[ "$?" -eq '0' ]]; then
docker container run --name=gin-gotest -d -p 8200:8000 go-gin
echo "更新成功"
else
docker container run --name=gin-gotest -d -p 8200:8000 go-gin
echo "初始化成功"
fi
echo "部署完成"
复制代码
- 运行和调试
可以看到经过多次尝试之后我们总算成功了,现在让我们来点别的花样,比如给流程加一个飞书的群提示 机器人(主要是飞书的文档配置了一个webhook),我们需要按照文档,先创建一个群,然后按照图示操作 结合飞书官方文档配置一下就好了,比如我这里是一个非常简单的只是 配置了一段连接而已, 由于我们使用的webhook机制,所以我们配置好之后,先用postman试一下,如果么问题,那么你的飞书机器人将会被触发。 现在我们把它丢到 ci流程中去, 这里我丢到之后一个build success阶段,如果成功就在群里通报
#!/bin/bash
##############################################################
# 如果 container 不存在就创建 如果存在就update
##############################################################
docker stop gin-gotest
docker container rm -f $( docker ps -aq --no-trunc --filter name=gin-gotest)
if [[ "$?" -eq '0' ]]; then
docker container run --name=gin-gotest -d -p 8200:8000 go-gin
echo "更新成功"
else
docker container run --name=gin-gotest -d -p 8200:8000 go-gin
echo "初始化成功"
fi
echo "部署完成"
# 发送飞书通知,后续需要写一个服务 集成 自己的 账户体系
curl --location --request POST 'https://open.feishu.cn/open-apis/bot/v2/hook/youer-authkey' \
--header 'Content-Type: application/json' \
--data-raw '{
"msg_type": "post",
"content": {
"post": {
"zh_cn": {
"title": "项目更新通知",
"content": [
[
{
"tag": "text",
"text": "项目有更新: "
},
{
"tag": "a",
"text": "请查看",
"href": "http://192.168.1.5/big_ef/gitlab_test_ci"
}
]
]
}
}
}
}'
---
复制代码
总结
关于gitlab-runner 是迄今为止 本人接触过的比较简单成本比较低的CICD工具了,大多数的CICD工具都是如此,希望同学们好好学习,特别是Shell脚本的编写,作为一名开发不管是前端或者后端shell脚本编写是必备技能啊