基于docker-compose的Gitlab CI/CD实践&排坑指南

简介: 经过长时间实操验证,终于完成基于Gitlab的CI/CD实践,本次实践的坑位很多, 实操过程尽量接近最佳实践(不做hack, 不做骚操作),记录下来加深理解。

长话短说


经过长时间实操验证,终于完成基于Gitlab的CI/CD实践,本次实践的坑位很多, 实操过程尽量接近最佳实践(不做hack, 不做骚操作),记录下来加深理解。


看过博客园《docker-compose真香》一文的园友留意到文中[把部署dll文件拷贝到生产机器],现场打包成镜像并启动容器,并没有完成CI/CD.


P1:Gitlab CI/CD原理和Gitlab Runner安装(这里使用shell执行器)


P2:基于Docker-compose的Gitlab CI/CD 实践:

  • 宏观业务架构图


  • .gitlab-ci.yml文件


  • 项目部署文件


Gitlab CI/CD部署准备


Gitlab CI/CD原理

  • 4d73250f3d80359bf897944518b337e2.png


  • Gitlab CI/CD   存储[构建][构建状态]的api应用程序, 提供友好的管理界面,  构建过程由 .gitlab-ci.yml文件定义(该文件一般置于代码仓库的根目录)


  • Gitlab Runner 执行构建任务的应用程序,可独立部署,如上图所示其通过api与Gitlab Server交互


搭建Gitlab CI/CD环境


Gitlab CI/CD提供配置界面(项目菜单栏-设置-CI/CD),可指定

  将要使用何种形式的Runner

  配置Runner要用到环境变量


界面配置权限取决于你在Gitlab Server的角色 + https://docs.gitlab.com/ee/user/permissions.html


本次手动设置特定Gitlab Runner


Runner安装完毕,注册Runner(与Gitlab Projects实例建立绑定关系)


注册时要关注的两个配置:


  • Tags    与此Runner相关的任务标签, 用于在共享Runner中区分不同的Project,.gitlab-ci.yml会用到


  • Runner Executor    执行构建任务的方式,这里使用shell方式


Shell是最简单的配置执行器,需要将构建所需的所有依赖项手动安装在安装了Runner的同一台计算机上。


注册过程和结果请参考下图:


02c8a709fb0366da8f53c26548120c71.jpg


Gitlab CI/CD实践


宏观业务架构图


cd902e66f5a2cf0bdeac2bad543dc822.png

原则上不允许自动部署Prod,本次使用Gitlab Runner服务器作为Gitlab CD的部署机器。


Gitlab-CI Pipeline构建ReceiverAPPwebAPP镜像(附带本次git:tag)并推送到hub.docker.com;


Gitlab-CD docker-compose拉取远端nginxReceiveAPPwebapp镜像启动容器。

287976ada506d3ac8d80633fa2d92e8e.png


  • Pipeline对每一次提交或合并都会执行build任务,形成Continous Intergation


  • Pipeline对git: tag会触发build_Image任务成功之后构建deploy:staging任务这样就能形成基于git:tag的部署版本管理(部署出错,也能很快回滚到上次的部署tag)


.gitlab-ci.yml文件

   

以上Gitlab Pipeline定义build->build_image->deploy3个任务某些任务还包括不同分支Job,写.gitlab-ci.yml 的过程就是将以上执行动作脚本化。


    stages:  - build  - build_image  - deploy
    variables:         # CI_DEBUG_TRACE: "true"                                           deploy_path: "/home/xxxx/eqidmanager"     # CI变量,用于配置部署目录
    before_script:  - "docker info"
    build:  stage: build  script:     - "for d in $(ls src);do echo $d;prog=$(pwd)/src/$d/$d.csproj; dotnet build $prog; done"  tags:                                                     - another-tag
    build_image:EqidManager:  stage: build_image  script:    - dotnet publish src/EqidManager/EqidManager.csproj  -c release -o ../../container/app/publish/        - docker build --pull  -t $CI_REGISTRY_USER/eqidmanager:$CI_COMMIT_REF_NAME  container/app    - docker login -u $CI_REGISTRY_USER  -p $CI_REGISTRY_PASSWORD          - docker push $CI_REGISTRY_USER/eqidmanager:$CI_COMMIT_REF_NAME       tags:        - another-tag  only:                #Pipeline Job构建策略,代码仓库打tag会执行该任务, 支持正则    - tags
    build_image:EqidReceiver:  stage: build_image  script:    - dotnet publish src/EqidReceiver/EqidReceiver.csproj  -c release -o ../../container/receiver/publish    - docker build -t $CI_REGISTRY_USER/eqidreceiver:$CI_COMMIT_REF_NAME container/receiver    - docker login -u $CI_REGISTRY_USER  -p $CI_REGISTRY_PASSWORD    - docker push $CI_REGISTRY_USER/eqidreceiver:$CI_COMMIT_REF_NAME  tags:     - my-tag  only:    - tags
    deploy:staging:  stage: deploy  script:    - cd $deploy_path    - export TAG=$CI_COMMIT_REF_NAME        # 引入本次CI的git:tag名称,覆盖.env文件默认配置    - "docker-compose -f docker-compose.yml -f docker-compose.prod.yml build"                            - "docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d"   tags:     - my-tag
    deploy:prod:  stage: deploy  script:    - # TODO 需要写脚本登陆到Prod机器上    - export TAG=$CI_COMMIT_REF_NAME            - cd $deploy_path    - "docker-compose -f docker-compose.yml -f docker-compose.prod.yml build"    - "docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d"   tags:    - my-tag  when: manual


    这里有些知识点坑位需要指出:


    第8行:预先定义的环境变量该变量定义gitlab CD的部署目录


    第16行: 对src开发目录下两个程序执行dotnet build命令


    第17行:tags定义具备该tags的Runner可以执行该任务,注意这里的tags必须是字符串数组


    第23-26行:构建镜像并推送到镜像仓库的过程,用到两类CI变量


     - 密钥变量CI_REGISTRY_USERCI_REGISTRY_PASSWORD,可在Gitlab-CI界面配置


     - 预定义变量CI_COMMIT_REF_NAME该变量标记构建项目的git:branch或git:tag名称,用于生成Image:Tag


    注意变量可被重写,重写优先级:http://www.ttlsa.com/auto/gitlab-cicd-variables-zh-document/


    第29行:only定义此Job只在产生git:tag时被触发与上面我们使用CI-COMMIT_REF_NAME 变量相呼应


    第47行:Gialab-CI pipeline每个Job会重新拉取git源码执行Job任务(可登录到Gitlab Runner工作目录下观察Runner执行过程),CD时需要选择合适目录,这是deploy_staging上使用deploy_path CI变量的原因


    第48行:注入本次Gitlab-CI git:tag名称实际上是覆盖了.env同名环境变量


    第49行:若存在docker-compose.yml、docker-compose.override.yml 两个文件,docker-compose命令会自动merge这2个文件(使用docker-compose config命令查看merge之后的结果)。


    第64行:前置任务未出错,会自动执行后继任务;而when指令定义该任务需要界面上手动执行


    部署目录

     

    在Gitlab Runner服务器的{deploy_path}路径下建立了如下部署文件:


      ├── appsettings.secrets.json├── docker-compose.prod.yml├── docker-compose.yml├── .env├── EqidManager.db├── nginx│   ├── Dockerfile│   └── nginx.conf└── receiver.secrets.json
      • 部署目录定义docker-compose.yml、docker-compose.prod.yml 两个yml文件,前者定义常规容器服务,后者定义适用于本部署环境的附加服务


      • 密钥文件不要进入代码管理,因此我们定义appsetting.secrets.json 和 receiver.secrets.json密钥文件,由dccker-compose.yml挂载进入容器


      • env文件存储相对固定且与本次docker-compose命令相关的环境变量,docker-compose命令默认寻找同级目录下.env文件


        ------.env 文件----TAG=master    # 该TAG变量会在Pipeline:deploy_staging任务中被覆盖,形成基于git:tag的imageName:tagdocker_host=172.16.1.1COMPOSE_PROJECT_NAME=EqidManagerDOCKER_REGISTRY=***


        Project打上git:tag之后,触发Gitlab Runner CI/CD Pipeline:


        跳转到部署目录->应用本次git:tag->执行docker-compose命令拉取指定tag镜像并启动容器。


        That'all, 本次应用Gitlab Runner(shell执行器)实践CI/CD, Gitlab菜单界面有所有构建构成的日志(便于排查构建问题);另外上文对于关键知识均附带传送门,可进一步对比研究。

        相关文章
        |
        7天前
        |
        jenkins Java 持续交付
        Jenkins与Docker的自动化CI/CD实战
        Jenkins与Docker的自动化CI/CD实战
        |
        12天前
        |
        存储 Kubernetes Docker
        构建高效稳定的Docker容器集群:从原理到实践
        【4月更文挑战第19天】 在当今微服务架构盛行的时代,容器化技术已经成为了软件开发和部署的标准实践。本文深入探讨了如何利用Docker容器技术,结合Kubernetes集群管理工具,构建一个高效、稳定且可扩展的容器化环境。文章首先简述了Docker的核心原理及其优势,接着详细阐述了Kubernetes的基本概念与组件,最后通过一个实际案例来指导读者如何从零开始搭建并优化一个基于Docker和Kubernetes的容器集群系统。
        19 1
        |
        19天前
        无缝构建与部署:GitLab CI/CD首秀的实战攻略
        无缝构建与部署:GitLab CI/CD首秀的实战攻略
        38 0
        无缝构建与部署:GitLab CI/CD首秀的实战攻略
        |
        19天前
        |
        Docker 容器
        GitLab Runner注册大揭秘:高效CI/CD的入门指南
        GitLab Runner注册大揭秘:高效CI/CD的入门指南
        34 0
        GitLab Runner注册大揭秘:高效CI/CD的入门指南
        |
        19天前
        |
        存储 持续交付 API
        GitLab CI/CD简介:构建持续集成与持续交付的全方位指南
        GitLab CI/CD简介:构建持续集成与持续交付的全方位指南
        31 0
        GitLab CI/CD简介:构建持续集成与持续交付的全方位指南
        |
        1月前
        |
        前端开发 Ubuntu 开发者
        【Docker系列】Docker-核心概念/常用命令与项目部署实践
        【4月更文挑战第1天】 Docker是容器化技术,打包应用及依赖,实现快速部署。核心概念包括镜像、容器和仓库。镜像是只读模板,容器是镜像运行实例,仓库用于存储和分发镜像。常用命令如`docker search`、`docker pull`、`docker images`、`docker ps`等。安装Docker在Ubuntu上涉及`apt-get update`、`install docker-ce`等步骤。了解这些基础,开发者能更高效地部署和管理应用。Docker简化了环境配置,增强了软件的可移植性和扩展性,是现代开发的必备技能。
        285 3
        |
        1月前
        |
        Shell 网络安全 开发工具
        docker 安装 gitlab 教程详解
        docker 安装 gitlab 教程详解
        43 0
        |
        2月前
        |
        Devops 开发工具 数据安全/隐私保护
        Docker Swarm总结+CI/CD Devops、gitlab、sonarqube以及harbor的安装集成配置(3/5)
        Docker Swarm总结+CI/CD Devops、gitlab、sonarqube以及harbor的安装集成配置(3/5)
        63 0
        |
        2天前
        |
        存储 虚拟化 数据中心
        |
        1天前
        |
        存储 Linux 文件存储
        Linux使用Docker部署Traefik容器并实现远程访问管理界面-1
        Linux使用Docker部署Traefik容器并实现远程访问管理界面