Gitlab CI/CD教程以及实战docker自动部署前端项目(全)

前言

主要用来记录自已怎么通过gitlab-cicd实现自动化部署
通过git代码来触发自动更新

具体的参考资料如下:

  1. GitLab CI/CD 教程
  2. 官网gitlab对cicd的说明文档

主要的视频链接如下:
GitLab CI/CD系列教程
以下博客知识点大部分来源于该b站视频知识(非常不错,推荐)

关于下面的技术点中遇到的错误以及实战遇到的错误
都可看我这篇博客知识:
Gitlab CI/CD中的yml遇到的错误分析含解决方法(全)

1. 技术知识

1.1 docker安装gitlab

可以使用公司的gitlab或者官方的gitlab的平台(使用公司平台上的gitlab比较简单,下面实战的情况我也会讲到)
个人的话也可 通过docker安装gitlab
如果通过docker安装gitlab,具体安装如下:

sudo docker run --detach \
  --hostname 域名
  --publish 443:443 --publish 80:80 --publish 222:22 \
  --name gitlab \
  --restart always \
  --volume /srv/gitlab/config:/etc/gitlab \
  --volume /srv/gitlab/logs:/var/log/gitlab \
  --vlolume /srv/gitlab/data:/var/opt/gitlab \
  gitlab /gitlab-ce:last

关于以上命令的部分讲解:

detach是后台运行,
宿主机的端口号:容器端口号
restart always自动会重启
目录的映射,本地配置或者查看等等(保存在本地)

容器被删除或者清空就没有了,所以挂载到本地是不错的选择

执行上面的命令之后
通过docker container ls -a

通过docker logs -f gitlab 即可查看其启动的日志,-f的参数是实时日志的意思

如果要让域名解析成功,要添加一个云解析也就是dns解析,才可通过域名进行访问
否则只能进行服务器的ip进行访问

关于gitlab的项目推送以及拉取
可看我之前对git的讲解文章:

  1. Git的安装配置超详细版本(全)
  2. Git从入门到精通(全)
  3. GitHub中配置ssh来clone以及pull等(图文版本解释)

1.2 docker安装gitlab-runner

前言知识:

  1. 两大要素分别为gitlab-runner的环境,以及.gitlab-ci.yml的配置文件书写

  2. cicd就是持续集成以及持续的部署
    持续集成就是提交一个分支的时候会去检查代码模块

  3. 一条流水线pipeline有多个stages,每个stages有多个jobs(任务是流水线最小的单元)
    这些任务都是在gitlab-runner在跑,gitlab-runner就是一个软件,就是给流水线提供一个运行环境

一句话总结:要配置cicd的自动话部署,就要设置一个gitlab-runner的环境
yml文件就是流水线的任务以及执行任务

安装gitlab-runner的命令方式如下:

docker run -d --name gitlab-runner --restart always \
-v /srv/gitlab-runner/config:/etc/gitlab-runner \
-v /var/run/docker.sock:/var/run/docker.sock \
gitlab/gitlab-runner:latest

具体配置文件就是启动的名字,以及宕机可重启,挂载文件,拉取的版本方式等等

执行启动之后可通过docker ps查看


怎么将gitlab以及gitlab-runner联系在一起
在gitlab中的设置中就可看到runners,通过查看runner就可看到其url以及token
在这里插入图片描述
执行命令如下:

docker run --rm -v /srv/gitlab-runner/config:/etc/gitlab-runner gitlab/gitlab-runner register \
--non-interactive \
--executor "docker" \
--docker-image alpine:latest \
--url "https://git-cc.nie.netease.com/" \
--registration--token "xxx" \
--description "runner05-4000-git-cc-1" \
--tag-list "docker" \
--run-untagged="ture" \
--locked="false" \
--access-level="not_protected"

具体其配置参数如下:
tag就是运行的runner,需要使用没有标签的tag-list
executor就是执行器,可通过docker或者k8s等等

1.3 .gitlab-ci.yml编写

关于这部分内容的书写可看这个up主相关系列的内容(超赞)
.gitlab-ci.yml关键词概览解析(一)

一般放在根目录文件下

  • image 指定使用node的基础环境变量
  • stages 指定三个阶段,(lint-code验证前端代码,前端代码没有lint可以不用这个)
  • cache (项目名称,缓存的路径)

如果不指定stages的话,默认是test

stages:
  - line code
  - install
  - build
  - deploy
  - clean

job 0:
  stage: install
  script: echo 'intall'

job 1:
  stage: build
  script: echo 'build'
  
job 2:
  stage: deploy
  script: echo 'deploy'

linecode是验证代码

script主要是执行脚本,每个任务都要进行script,每个任务都是一个单行的脚本输出,如果要执行多行的脚本,则通过如下:(retry 是重试次数,放在script执行)

  script: 
    - echo 'deploy'
    - echo ‘xx’

如果两个任务都是一样的,并不是并发执行,而是按照顺序的执行
每一个流水线只有一个执行,主要为了减少消耗,如果要配置的话,通过gitlab-runner进行配置多任务执行


另外几个常用的关键字

  • images:指定一个镜像作为基础的运行环境
  • tags:关键词指定runner,tags的取值范围在该项目中可见的runner tags中
  • only/except:限定当前任务执行的条件
  • when:在某些特殊情况或者出现故障进行运行
  • cache:当前工作环境目录中的一些文件,用于各个任务初始化的时候进行恢复

具体的执行命令如下:(下面的命令都进行了注释)
执行的script要使用npm,所以一开始要引入node的这个包,alpine为精简版的格式版本

image: node:alpine

stages:
  - install
  - build
  - deploy

cache:
  key :vitepro # 代表缓存的版本,因为每个阶段都会把这个生成的包删除,所以定义一个全局变量来缓存这个cache包
  paths: # 代表缓存的包名,前端的依赖包都是node_modules,具体看你项目生成的包
    - node_modules
    - html # 此处可不加,主要为了说明缓存的paths是一个数组,可以多缓存多个,这样进行缓存

job_install:
  stage: install
  tags: dockercicd1 # 指定运行的runner,因为不可指定全局的runner,所以在各个阶段都指定这个tags
  script: 
    - npm install

job_build:
  stage: build
  tags: dockercicd1 # 指定运行的runner,因为不可指定全局的runner,所以在各个阶段都指定这个tags
  script: 
    - npm run build 
  only:
    - release # 指定的是一个分支,在master的分支会看不到这个任务,执行的时候被隐藏起来不被看到
  
job_deploy:
  stage: deploy
  tags: dockercicd1 # 指定运行的runner,因为不可指定全局的runner,所以在各个阶段都指定这个tags
  script: 
    - echo 'deploy'
  when: manual # 此处配置成一个手动的内容,可加可不加

1.4 使用docker部署前端项目

先修改一个docker的配置文件
docker 要配置一个目录卷,如果不配置的话就会出错,主要在runner配置文件里配置
在这里插入图片描述
具体配置方式如下:

  • vim /src/gitlab-runner/config/config.toml
    文件中主要的代码讲解,以及每个runner的配置,找到runner的配置

多少个流水线
多久检查一次流水线

在volumes的配置,配置docker的配置,多一个映射的配置
找到runner的name名字
修改下面的volumes,增加一些容器
主要参数如下:

/usr/bin/docker:/usr/bin/docker,/var/run/docker.sock:/var/run/docker.sock

添加的界面如下:
在这里插入图片描述


配置完成之后开始下面的步骤:

前面的gitlab以及gitlab-runer已经执行了
主要是yml文件的书写

此处讲解一下ym文件的书写:

image: node:alpine

stages:
  - install
  - lint-code
  - build
  - deploy

cache:
  key :vitepro # 代表缓存的版本,因为每个阶段都会把这个生成的包删除,所以定义一个全局变量来缓存这个cache包
  paths: # 代表缓存的包名,前端的依赖包都是node_modules,具体看你项目生成的包
    - node_modules

job_install:
  stage: install
  tags: dockercicd1 # 指定运行的runner,因为不可指定全局的runner,所以在各个阶段都指定这个tags
  script: 
    - npm install

job_build:
  stage: build
  tags: dockercicd1 # 指定运行的runner,因为不可指定全局的runner,所以在各个阶段都指定这个tags
  script: 
    - npm run build
    
job_deploy:
  stage: deploy
  image: docker #下面有运行到docker,所以要引入docker的镜像
  tags: dockercicd1 # 指定运行的runner,因为不可指定全局的runner,所以在各个阶段都指定这个tags
  script: 
    - docker build -t xx . #产生这个镜像
    - if [ $(docker ps -aq --filter name==xx-container) ]; then docker rm -f xx-container;fi   # 判断当前有没有这个容器
    - docker run -d -p 15599:15599 --name xxxx

如果npm install的包比较多,可以通过重试次数或者缓存进行优化等等
-t 后面接的是镜像名称
本地可能已经有了这个容器,所以要提前判断是否有这个容器并且进行删除

  • docker build -t xx . 这一步要成功的话,要编写一个Dockerfile文件

主要的文件格式如下:

FROM node:latest as builder
WORKDIR /app
COPY package.json .
RUN npm install -- registry==http://registry.npm.taobao.org
COPY . .
RUN npm run build

FROM nginx:latest
COPY -- from=builder /app/dist /usr/share/nginx/html

1.5 使用阿里云oss部署前端项目

oss的介绍以及创建bucket
oss本身就是服务器,本身可以设置静态网站的托管,以及cdn的加速,绑定域名等等
通过创建Bucket设置项目,存储项目的文件

将文件上传到oss服务器
可以使用命令行工具ossutil、图像化工具ossbrowser、数据迁移工具ossimport等

image: node:alpine

stages:
  - install
  - lint-code
  - build
  - deploy

cache:
  key :vitepro # 代表缓存的版本,因为每个阶段都会把这个生成的包删除,所以定义一个全局变量来缓存这个cache包
  paths: # 代表缓存的包名,前端的依赖包都是node_modules,具体看你项目生成的包
    - node_modules

job_install:
  stage: install
  tags: dockercicd1 # 指定运行的runner,因为不可指定全局的runner,所以在各个阶段都指定这个tags
  script: 
    - npm install

job_build:
  stage: build
  tags: dockercicd1 # 指定运行的runner,因为不可指定全局的runner,所以在各个阶段都指定这个tags
  script: 
    - npm run build
  artifacts:
    paths:
      - dist/ # 存储起来生成制品,每个任务都可使用

job_deploy_oss:
  stage: deploy
  tags: 
    - vite
  script:
    - wegt htttp://gosspublic.alicdn.com/ossutil/1.6.18/ossutil64 # 下载到这个目录
    - chmod 755 ossutil64  #给这个权限赋值
    - ./ossutil64 config -e ${endpoint} -i ${accessKeyID} -k ${accessKeySecret} -L CH --loglevel debug -c ~/.ossutilconfig 
    - ./ossutil64 -c ~/.ossutilconfig cp -r -f dist oss://xxx/
   when: manual

关于这个命令的补充说明- ./ossutil64 config -e ${endpoint} -i ${accessKeyID} -k ${accessKeySecret} -L CH --loglevel debug -c ~/.ossutilconfig
将其文件配置好权限之后写入到oss的一个配置文件中

  • endpoint是区域地址,是oss的一个地址
  • accessKeyID是阿里云内的所有资源
  • accessKeySecret是密钥

后面的具体参数L是选择语言,选择ch为utf-8,loglevel是日志等级,-c为配置文件

./ossutil64 -c ~/.ossutilconfig cp -r dist oss://xxx/, cp上传到oss文件
c是指定配置文件,cp是上传文件,r是递归上传,f为强制覆盖原有的文件(如果不加这个参数,修改代码自动部署更新不成功)

跟上面的代码模块不同之处在于这里还有一个生成制品

 artifacts:
    paths:
      - dist/ # 存储起来生成制品,每个任务都可使用

主要为了后续每个任务都使用到,也节省了时间

1.6 变量的注入以及使用

比如账号密码的使用不让别人看到
可以通过yml文件中通过variables定义
通过pipeline中预定义使用变量或者在项目中设置变量
这些变量可以设置key value或者文件格式

流水线中设置变量定义

variables:
  MT_VAR: " my name is manongyanjiuseng" 

log_var:
  script:
    - echo $MT_VAR

项目中设置变量
可通过pipeline中设置key value(变量不可使用空格,要大于8个,不可和cicd的一些变量冲突)
protect variable 主要是master分支不可使用
mask可以进行遮罩
项目中的书写如下:

log_project_var:
  script:
    - echo $NAME

类似前面所讲到的docker部署前端项目
通过存储镜像或者容器设置成变量存储,只需要修改一次即可

导出所有变量可以通过export进行输出

get_all_var:
  script:
    - export

变量的使用可以 如下:url name inclued 制品名称 镜像名称等等

1.7 流水线的类型以及触发方式

流水线的基本类型:
基本流水线、DAG流水线、多项目流水线、父子流水线以及合并请求流水线

流水线的触发方式有:
推送代码、定时触发(在设置中的schedule)、url触发以及手动触发


DAG流水线可以挂平台,测试部署的时候会有不一样的依赖平台
例子:

stages:
  - build
  - test
  - deploy

image:alpine

build_a:
  stage: build
  script:
    - echo 'build_a'

build_b:
  stage: test
  needs: [build_a]
  script:
    - echo 'build_b'

test_a:
  stage: test
  needs: [build_a]
  script:
    - echo 'test_a'

test_b:
  stage: test
  needs: [build_b]
  script:
    - echo 'test_b'

deploy_a:
  stage: deploy
  needs: [test_a]
  script:
    - echo 'deploy_a'

deploy_b:
  stage: deploy
  needs: [test_b]
  script:
    - echo 'deploy_b'    

其DAG的流水线具体如下:
在这里插入图片描述
needs表明依赖什么任务的流水线


父子流水线:(标准的gitlab流水线就是父子)

stages:
  - test
  - triggers
  - deploy

testjob:
  stage: test
  script: echo 'test'

trigger_a:
  stage: triggers
  trigger: 
    include: a/.gitlab-ci.yml # 当前项目包括另外的流水线
  rules: # 修改这个文件就会触发
    - changes:
      - a/*

trigger_b:
  stage: triggers
  trigger: 
    include: b/.gitlab-ci.yml
  rules:
    - changes:
      - b/*

先执行上游的流水线,在执行下游的流水线


多项目流水线(微服务流水线,想要拆成多项目,也就是同时发版),由入口流水线触发其他任务的流水线

stages:
  - test
  - triggers
  - deploy

testjob:
  stage: test
  script: echo 'test'

trigger_a:
  stage: triggers
  trigger: 
    include: a/.gitlab-ci.yml # 当前项目包括另外的流水线
  rules: # 修改这个文件就会触发
    - changes:
      - a/*

trigger_b:
  stage: triggers
  trigger: 
    include: b/.gitlab-ci.yml
  rules:
    - changes:
      - b/*

trigger_b:
  stage: deploy
  trigger: 
    project: root/plain_html # 触发什么项目
    branch: master
    strategy: depend # 触发流水线会在这个任务上显示出来

合并流水线:
合并的时候做一些验证,主要加一些参数
具体如下:

only:
  - merge_requests

流水线触发的方式:

curl -X POST \
  -F token=xx \
  -F ref=master \
  http://gitlab.yuming

其他的方式在gitlab cicd 的设置中 都可看到

1.8 ssh远程服务器部署

关于ssh访问GitHub
之前我也写过一篇文章
也可参考此处:
GitHub中配置ssh来clone以及pull等(图文版本解释)

生成公钥和密钥

ssh-keygen -t rsa -b 2048 -C "zhanghao"

# 复制公钥到服务器上,找到当前路径
scp -r id_ras.pub zhanghao@ip:/root/.ssh/authorized_keys

将其密钥保存在cicd设置中

yml文件的书写:

image: node:latest

stages:
  - install
  - build
  - deploy

cache:
  key:
    files: 
      - package-lock.json # 锁定依赖包的版本
  paths:
    - node_modules

.set-tags: &set-tags # 定义一个锚点
  tags:
    - vite

install _job:
  <<: *set-tags #之后引用锚点,将其引入这里
  stage: install
  script: npm install

deploy_job:
  <<: *set-tags
  stage: build
  script: npm run build
  artifacts:
    paths:
      - dist
#把这个制品恢复到下面

deploy-job:
  <<: *set-tags
  stage: deploy
  #执行script前 执行before_script安装一些环境
  before_script:
    - 'which ssh-agent || ( yum update -y && yum install openssh-client git -y)'
    - eval $(ssh-agent -s)
    - echo "SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
    - mkdir -p ~/.ssh
    - chmod 700 ~/.ssh

	- ssh-keyscan 服务器ip >> ~./ssh/host # 保存在host的目录
	- chmod 644 ~/.ssh/host 
  script:
    - echo 'start scp'
    - scp -r dist root@ip:/usr/local/www # 本机的工作目录上传到服务器

关于该文件,其实官方的代码模块也有此讲解

1.9 流水线调试手段

关键词:release、timeout以及rousource_group

interruptible 新的流水线被触发了,旧的流水线就会被取消,保留最新的流水线
有利于防止资源的消耗,自动的取消达到一个良好的环境
前提是勾选gitlab中的这个选项(搭配使用)
在这里插入图片描述
yml文件的书写:

stages:
  - install
  - build
  - deploy

install_job:
  stage: install
  script: 
    - echo 'start'
    - sleep 60
    - echo 'end '
  interruptible: true # 默认是false

build_job:
  stage: build
  script: 
    - echo 'start'
    - sleep 60
    - echo 'end '
  interruptible: true

create_release: # 把长生的镜像放到release
  image: registry.gitlab.com/gitlab-org/release-cli:latest
  stage: build
  script: echo 'start'
  release:
    tag_name: $CI_COMMIT_TAG #名称如果没有的话会自动设置tag_name
  only:
    - tags # 在项目的仓库中打了tags的时候就会执行这个

deploy:
  stage: deploy
  environment:
    name: staging
  script:
    - echo 'start '
    - sleep 120 
  resource_group:prod # 配置了字符串
  • timeout:时间如果运行太久的话会自动被取消
  • resource_group:限定并发任务,避免了部署任务的不可控

调出debug设置
已经确定你在服务器上安装了gitlab-runner
所以只需要在配置文件中添加如下设置:

vim /srv/gitlab-runner/config/config.toml

增加如下设置:

[session_server]
  listen_adress = "[::]:8093"
  advertise_adress = 'ip:8093'
  session_timeout = 1800

之后在pipeline的时候出错就会有debug


部署冻结:(此时间不可部署)确保环境的安全
在设置中添加限制时间
在yml文件中添加如下代码:

deploy:
  stage: deploy
  environment:
    name: staging
  script:
    - echo 'start '
    - sleep 120 
  resource_group:prod # 配置了字符串
  rules:
    - if: $CI_DEPLOY_FREEZE == null # 如果时间为空或者不在这个范围才可部署

2. docker部署前端项目(内网)

以下代码自已写的
(运行时间4分钟),可大致参考

自带的gitlab,所以没有通过docker安装gitlab

只需要在服务器上安装gitlab-runner来了解gitlab即可

通过docker安装gitlab-runner,输入与gitlab搭配的桥梁的url以及token桥梁

所以需要将其gitlab-runner的配置文件中的auth写入

variables:
  DOCKER_AUTH_CONFIG: '{"auths": {"$AUTH_USER": {"auth": "$AUTH_KEY"}}}'
    
# 此处用内网的镜像 是因为docker的镜像有拉取限制
image: 内网域名/mirror_docker.io/library/node:latest
 
stages:
  - install
  - build
  - deploy

cache:
  key: xx# 项目名称,这个可以随意,如果不取系统会默认给你一个key
  paths:
    - node_modules ##指定缓存路径

job_install:
  stage: install
  tags:
    - xx-docker # 指定运行的runner,此处在gitlab中的设置 runner可查看
  script:
    - npm install 
  
    
job_build:
  stage: build
  tags:
    - xx-docker
  script:
    - npm run build 
  
    
job_deploy:
  stage: deploy
  image: 内网域名/mirror_docker.io/library/docker:stable-dind
  tags:
    - xx-docker
  script:
    - docker build -t xx.
    - if [ $(docker images -q -f dangling=true) ]; then docker rmi $(docker images -q -f dangling=true); fi 
    - if [ $(docker ps -aq --filter name=xx-container) ]; then docker rm -f $(docker ps -aq --filter name=xx-container);fi 
    - docker run -d -p 8082:80 --name xx-container xx# 使用新的容器
    - echo 'start deploy'

关于上面文件中的build -t代码模块的执行
主要通过Dockerfile进行编译:

FROM node:latest as build

WORKDIR /xx
COPY package.json .
RUN npm install --registry=http://registry.npm.taobao.org
COPY . .
RUN npm run build

From nginx:latest

COPY --from=build /xx/build /usr/share/nginx/html

以上代码模块是打通内网的镜像
通过服务器ip地址:8082地址访问

如果是打通外网,则还需要配置域名以及dns解析


版权声明:本文为weixin_47872288原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。