GitLab-CI/CD 搭建

docker搭建

# 更新apt包索引
sudo apt-get update

# 卸载旧版的docker
sudo apt-get remove docker docker-engine docker.io containerd runc

# 一键安装docker
curl -sSL https://get.daocloud.io/docker | sh

gitlab搭建

  1. 安装gitlab
# docker安装gitlab镜像
docker pull gitlab/gitlab-ce:latest

# 运行gitlab的docker
docker run \
    --publish 8443:443 --publish 8080:80 --publish 2222:22 \
    --name gitlab \
    --volume /home/gitlab/config:/etc/gitlab \
    --volume /home/gitlab/logs:/var/log/gitlab \
    --volume /home/gitlab/data:/var/opt/gitlab \
    gitlab/gitlab-ce
  
 # 暂时关闭服务器防火墙
 systemctl stop firewalld
 
 # 浏览器输入 http://ip:port 访问gitlab
  1. 优化gitlab的内存占用
# 进入到gitlab的bash
docker exec -it ${gitlab的docker id} /bin/bash 

# 编辑gitlab的配置文件 
vi /etc/gitlab/gitlab.rb

###### 修改配置内容start ######

puma['worker_processes'] = 4 # 去掉#注释 设置进程 不能低于2
puma['worker_timeout'] = 60 # 设置超时时间

###### 修改配置内容end ######

# 重启gitlab
gitlab-ctl restart
  1. 配置gitlab clone克隆地址
# 进入到gitlab的bash
docker exec -it ${gitlab的docker id} /bin/bash 

# 编辑配置文件
vi /etc/gitlab/gitlab.rb

###### 修改配置内容start ######
external_url 'http://ip:port'  # 访问地址 port为docker run时设置的8080

gitlab_rails['gitlab_shell_ssh_port'] = 2222 # ssh端口号 为docker run时设置的2222

gitlab_rails['gitlab_ssh_host'] = ip # ssh的访问ip
###### 修改配置内容end ######

# 修改配置文件
vi /opt/gitlab/embedded/service/gitlab-rails/config/gitlab.yml

###### 修改配置内容start ######
host ip地址  # 设置ip地址
port 访问端口 # 设置访问端口 同external_url设置的端口号
###### 修改配置内容end ######

# 重启gitlab
gitlab-ctl restart

安装配置git-runner

# 安装git-runner
sudo docker run -d --name gitlab-runner --restart always \
  -v /home/gitlab-runner/config:/etc/gitlab-runner \
  -v /var/run/docker.sock:/var/run/docker.sock \
  gitlab/gitlab-runner:latest
 
# 注册
docker run --rm -v /srv/gitlab-runner/config:/etc/gitlab-runner gitlab/gitlab-runner register \
  --non-interactive \
  --executor "docker" \
  --docker-image alpine:latest \
  --url "" \
  --registration-token "" \
  --description "first-register-runner" \
  --tag-list "vue3-app" \
  --run-untagged="true" \
  --locked="false" \
  --access-level="not_protected"
  • 注册需要token和url,获取方式如下图

  • CI/CD配置yaml脚本需要的变量

编写.gitlab-ci.yml 🏁

stages:
  - init # 初始化
  - lint # 校验
  - build # 打包
  - deploy # 部署

# 在流水线中使用package.json缓存node_modules,只要package.json内容没变就一直使用缓存
cache:
  key:
    files:
      - package.json
  paths:
    - node_modules/

# npm i 安装
init:
  stage: init
  only: 
    refs: 
      - merge_requests
    variables:
      - $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "develop"
  script:
    - npm cache clean --force
    - npm install -g cnpm --registry=https://registry.npm.taobao.org
    - cnpm install
  after_script:
    - chmod a+x ./dingding.sh # 给钉钉的脚本添加权限
    - ./dingding.sh  # 执行钉钉脚本    

# 代码校验
lint:
  stage: lint
  only: 
    refs: 
      - merge_requests
    variables:
      - $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "develop"  
  script:
    - npm run lint:jsx
    - npm run lint:css
  allow_failure: true

# 开始构建
build:
  stage: build
  artifacts:
    # 文件名
    name: 'dist'
    # 过期时间
    expire_in: 60 mins
    # 需要打包目录
    paths:
      - dist/
  only: 
    refs: 
      - merge_requests
    variables:
      - $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "develop" # 表示只有往 develop分支提MR才会触发部署
  script:
    - npm run build:test    
  after_script:
    - chmod a+x ./dingding.sh # 给钉钉的脚本添加权限
    - ./dingding.sh  # 执行钉钉脚本

deploy:
  stage: deploy
  only: 
    refs: 
      - merge_requests
    variables:
      - $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "develop" # 表示只有往 develop分支提MR才会触发部署
  script:
    - 'which ssh-agent || ( apk update && apk add openssh-client)' # 预先装 ssh-agent
    - eval $(ssh-agent -s) # 启动服务
    - mkdir -p  /etc/ssh/
    - chmod 700  /etc/ssh
    - echo "$SSH_KNOWHOST" > /etc/ssh/known_hosts
    - echo "$SSH_PRIVATE_KEY" > /etc/ssh/id_rsa
    - echo "$SSH_CONFIG" > /etc/ssh/ssh_config.d/config.conf
    # 配置较低权限
    - chmod 600 /etc/ssh/id_rsa
    - chmod 600 //etc/ssh/ssh_config.d/config.conf
    - chmod 644 /etc/ssh/known_hosts
    # 注入密钥 
    - ssh-add /etc/ssh/id_rsa
    - ssh Aliyun "rm -rf /var/www/project/test"
    - scp -i /etc/ssh/id_rsa -r ./dist/ "$SSH_USERNAME"@"$SSH_HOST":/var/www/project/test/ 
  after_script:
    - chmod a+x ./dingding.sh # 给钉钉的脚本添加权限
    - ./dingding.sh  # 执行钉钉脚本
  when: on_success

钉钉配置

  1. 群助手设置

    • 创建群

    • 添加智能群助手

    • 添加自定义机器人

    • 配置机器人

  2. shell脚本

#!/bin/bash
##################
# 钉钉通知
# 自动化部署脚本中使用
##################

webhook="https://oapi.dingtalk.com/robot/send?access_token=${DINGDING_TOKEN}" # 你自己创建的钉钉机器人的地址

# 推送模板发送(模板拼接)
function sendDingTalkNotifications() {
      local text="#### git名称:${CI_PROJECT_NAME} \n ##### 构建分支:${CI_COMMIT_REF_NAME} \n ##### 构建状态:${DEPLOY_STATUS}\n #### 提交者:${GITLAB_USER_NAME}-${GITLAB_USER_EMAIL} \n\n\n ##### 更新内容:${CI_COMMIT_MESSAGE} \n ##### [流水线 Pipeline #${CI_PIPELINE_ID}](${CI_PROJECT_URL}/pipelines/${CI_PIPELINE_ID}) \n
      "
      curl POST "$webhook" -H 'Content-Type: application/json' -d "{\"msgtype\": \"markdown\",\"markdown\": {\"title\":\"${CI_PROJECT_NAME}\",\"text\": \"$text\"}}"
}

if [ "$?" -eq "0" ];then  # "$?" -eq "0" 表示上一句脚本执行成功,1的话表示失败
      case ${CI_JOB_STAGE} in
            "init")
                  DEPLOY_STATUS='初始化安装成功!'
                  sendDingTalkNotifications
            ;;
            "build") 
                  DEPLOY_STATUS='构建成功!'
                  sendDingTalkNotifications
            ;;
            "deploy") DEPLOY_STATUS='部署成功!'
                  sendDingTalkNotifications
            ;;
      esac
else
      case ${CI_JOB_STAGE} in
            "init"|"build") 
                  DEPLOY_STATUS='构建失败!'
                  sendDingTalkNotifications
            ;;
            "deploy")
                  DEPLOY_STATUS='部署失败!'
                  sendDingTalkNotifications
            ;;
      esac

fi

⚠️注意点

  • git-runner执行时候权限问题
    • 进入gitlab-runner的docker,修改/etc/passwd文件中的gitlab-runner的权限与root同等级0

参考文章

Docker 教程 | 菜鸟教程 (runoob.com)

使用docker搭建gitlab环境 - SegmentFault 思否

GitLab+Docker快速搭建CI/CD自动化部署 (juejin.cn)

利用 Gitlab CI/CD + Jenkins 实现自动构建,自动部署 (juejin.cn)

Gitlab-CI 配置文件 .gitlab-ci.yml 详细说明,基于官方文档翻译 | 渡渡岛 (ssoor.github.io)

设置 SSH 通过密钥登录 | 菜鸟教程 (runoob.com)

GitLab 14 轻量化运行方案 - 苏洋博客 (soulteary.com)

前端工程化之 CI/CD | Zander Hsueh (xuezenghui.com)