Day18 - GitLab CI 自动建置 Docker Image

前言

上回说到 CI/CD 的第一步会是 Build ,今天就来实际了解如何建置 Build Stage。

Build 相关配置

要如何使用专案里的 Dockerfile 自动建置 Image,需要先了解 GitLab CI 里的 Job 是如何运行的,在.gitlab-ci.yml中定义 Job 的格式如下

job-name:
  stage: stage-name
  script:
    - echo "script"

对流水线中每一个 Job ,GitLab Runner 会透过 Docker 启动 Container 做为此 Job 的环境,而容器要使用什麽 Image 可以在 .gitlab-ci.yml 上定义,会根据要下达的指令定义所需 Image 。

https://ithelp.ithome.com.tw/upload/images/20210918/20139235D6ambEPOZ9.png

像是Script 中若有 python xxx.py 的指令,可以选择使用 python 的 Image 做为 Job 的容器。

而现在的目标是希望在 Job 中能够建置 Image ,也就是说,会需要在 script 里会下达如 docker build 的指令,所以要使用的 Image 就会是 Docker 本身,在 Docker 里建置 Docker 容器,这种作法称为 Docker-in-Docker ,在.gitlab-ci.yml可以这样配置

image: docker

services:
  - docker:dind

在 GitLab 文档中的 Use Docker to build Docker imagesDocker-in-Docker 方法的详细介绍。

这样就可以 Build Docker Image 了,但紧接着会遇到下一个问题,每一次 Job 运行完成後 GitLab Runner 会将容器删除,所以 Build 好的 Image 需要先 Push 到可以保存的地方,而 GitLab 很好心的提供了 GitLab Container Registry ,让我们可以储存在 CI/CD 运行时建置出的 Image。

准备工作差不多完成,可以开始撰写 .gitlab-ci.yml 了,一开始会将重复使用的值定义为 variabes,如 CI_IMAGE 就是保存在 GitLab Registry 的 Image 名称。为了区别每次流水线建置出的 Image , Tag 会打上本次 Commit 产生的 SHA 来保证名称唯一性,在 Predefined variables reference 有参数可以直接代入。

variables:
  IMAGE_NAME: node-project
  CI_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA

$CI_REGISTRY_IMAGE 为此专案 GitLab Container Registry 的位置,而 $CI_COMMIT_SHORT_SHA 是 SHA 的前八码。

接着在 Build Job 中,透过 docker build 以及 docker push 建置 Image 并上传到 Registry ,因为需要有上传权限,所以会先使用 docker login 登入取得 Push 权限。

build:
  stage: build
  only:
    - dev
    - master
  before_script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
  script:
    - docker build -t $CI_IMAGE .
    - docker push $CI_IMAGE

有了 Image 後,接下来的 Job 就能使用 docker pull 将 Image 下载下来进行其他操作,像是在 Test Job 就可以使用 docker run <image> <command> 运行测试脚本。

test:
  stage: test
  only:
    - dev
    - master
  before_script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
  script:
    - docker pull $CI_IMAGE
    - docker run $CI_IMAGE echo "run test script here"

基本概念大致介绍完成,就来实际建立 Build Stage 吧!

建立 Build Stage

  1. 进入 Cloud Shell 网站

  2. 点击左上 Explorer -> Open Folder -> 选择 project 资料夹 -> Open

  1. 点击 .gitlab-ci.yml 档案并用以下内容取代

https://ithelp.ithome.com.tw/upload/images/20210918/201392356Z65TgVsn7.png

  • .gitlab-ci.yml
image: docker

services:
  - docker:dind
 
variables:
  IMAGE_NAME: node-project
  CI_IMAGE: $CI_REGISTRY_IMAGE/$IMAGE_NAME:$CI_COMMIT_SHORT_SHA

stages:
  - build
  - test
  - publish
  - stg-deploy
  - prod-deploy

build:
  stage: build
  only:
    - dev
    - master
  before_script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
  script:
    - docker build -t $CI_IMAGE .
    - docker push $CI_IMAGE

test:
  stage: test
  only:
    - dev
    - master
  before_script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
  script:
    - docker pull $CI_IMAGE
    - docker run $CI_IMAGE echo "run test script here"

publish:
  stage: publish
  only:
    - master
  script:
    - echo "publish job"

stg-deploy:
  stage: stg-deploy
  only:
    - master
  script:
    - echo "Staging deploy job"

prod-deploy:
  stage: prod-deploy
  only:
    - master
  script:
    - echo "Production deploy job"
  when: manual
  1. 点击终端机输入指令,建立 Commit 并 Push 到 GitLab 上
cd ~/project
git add .
git commit -m "add build and test stages"
git push origin master
  1. 输入 GitLab 帐号密码後按Enter
Username for 'https://gitlab.com': 
Password for 'https://[email protected]':
  1. GitLab 网站,点击之前建立的 web app 的 Repository

  2. 进入到 Repository 後,点击 CI/CD -> Pipelines

会看到新的 CI/CD Pipeline ,等待一段时间直到运行成功。

https://ithelp.ithome.com.tw/upload/images/20210918/20139235hYjGAlDjzY.png

  1. 接着检查 Image 是否储存成功,点击 Packages & Registries -> Container Registry

https://ithelp.ithome.com.tw/upload/images/20210918/20139235utmrYsGzNO.png

可以发现有 webapp 专案的 Image。

https://ithelp.ithome.com.tw/upload/images/20210918/20139235yu4KeMcWvQ.png

点击进去就能查看 Tag 名称。

https://ithelp.ithome.com.tw/upload/images/20210918/20139235LDpsOpeSU0.png

这里的 Tag 名称会跟本次 Commit 的前八码 SHA 吻合。

结论

今天完成了 Build Stage , 也简单说明 Test Stage 的方式,明天会学习如何将 Image 上传至 Google Container Registry 。


<<:  .NET Core第18天_InputTagHelper的使用

>>:  Day 6 阿里云架设网站-迁移上云端

[JS] You Don't Know JavaScript [this & Object Prototypes] - Object [上]

前言 我们在前面几章中介绍了this的绑定,说明了this最常被搞混的观点也介绍了如何透过call-...

#6 - Module Patterns

昨天我们讲解了如何 import 和 export 一个 modules,这时候你心中应该会有一个疑...

Day2 Develop Environment For Go

Preface 笔者将介绍自己所熟悉的Go开发环境如何设定,也就是MacOS(OS) + Golan...

(笔记D1) Spring MVC 框架

1-1 Spring MVC 特质 功能建构在 Servlet、JSP 规格基础上面发展,必须透过 ...

[Day11] CH08:积沙成塔——Array & ArrayList(上)

很快地已经学了十天,今天又是一个新的开始,今天要来认识「阵列」。 阵列(Array)是由同型别的相关...