如何有条件地更新CI / CD作业映像?

时间:2019-04-16 12:23:01

标签: docker gitlab gitlab-ci

我刚刚进入CI / CD的(绝妙)世界,并且拥有有效的管道。但是,它们并不是最佳的。

该应用程序是一个dockerized网站:

  • 源文件必须由webpack编译并以dist结尾
  • dist目录已复制到Docker容器
  • 然后远程构建和部署

我当前的设置还很幼稚(我添加了一些注释以表明为什么我认为各种元素都是必需/有用的):

# I start with a small image
image: alpine

# before the job I need to have npm and docker
# the problem: I need one in one job, and the second one in the other
# I do not need both on both jobs but do not see how to split them
before_script:
    - apk add --update npm
    - apk add docker
    - npm install
    - npm install webpack -g

stages:
    - create_dist
    - build_container
    - stop_container
    - deploy_container

# the dist directory is preserved for the other job which will make use of it
create_dist:
    stage: create_dist
    script: npm run build
    artifacts:
        paths:
        - dist

# the following three jobs are remote and need to be daisy chained
build_container:
    stage: build_container
    script: docker -H tcp://eu13:51515 build -t widgets-sentinels .

stop_container:
    stage: stop_container
    script: docker -H tcp://eu13:51515 stop widgets-sentinels
    allow_failure: true

deploy_container:
    stage: deploy_container
    script: docker -H tcp://eu13:51515 run --rm -p 8880:8888 --name widgets-sentinels -d widgets-sentinels

此设置适用于两个作业中都安装了npmdocker位。不需要此操作,这会减慢部署速度。 是否有办法说明需要为特定工作添加这样的软件包(而不是全局地对所有这些软件包添加)?

明确地说:这不是一个秀场停止者(实际上根本不可能成为一个问题),但我担心我实现这种工作自动化的方法不正确。

3 个答案:

答案 0 :(得分:1)

您不必为所有作业都使用相同的图像。让我向您展示我们的一条管道(部分执行),该管道执行类似的操作,仅使用composer代替php,npm

cache:
  paths:
    - vendor/

build:composer:
  image: registry.example.com/base-images/php-composer:latest # use our custom base image where only composer is installed on to build the dependencies)
  stage: build dependencies
  script:
    - php composer.phar install --no-scripts
  artifacts:
    paths:
      - vendor/
  only:
    changes:
      - composer.{json,lock,phar}  # build vendor folder only, when relevant files change, otherwise use cached folder form s3 bucket (configured in runner config)

build:api:
  image: docker:18  # use docker image to build the actual application image
  stage: build api
  dependencies:
    - build:composer # reference dependency dir
  script:
    - docker login -u gitlab-ci-token -p "$CI_BUILD_TOKEN" "$CI_REGISTRY"
    - docker build -t $CI_REGISTRY_IMAGE:latest.
    - docker push $CI_REGISTRY_IMAGE:latest

composer基本映像包含运行composer的所有必需软件包,因此,在您的情况下,您将为npm创建基本映像:

FROM alpine:latest 

RUN apk add --update npm

然后,在您的create_dist阶段使用此图像,并在其他阶段将image: docker:latest用作图像。

答案 1 :(得分:1)

除了为不同的作业引用不同的图像之外,您还可以尝试使用gitlab锚,该锚为作业提供可重复使用的模板:

.install-npm-template: &npm-template
  before_script:
  - apk add --update npm
  - npm install
  - npm install webpack -g

.install-docker-template: &docker-template
  before_script:
  - apk add docker

create_dist:
    <<: *npm-template
    stage: create_dist
    script: npm run build
...

deploy_container:
    <<: *docker-template
    stage: deploy_container
...

答案 2 :(得分:0)

尝试使用多阶段构建器,您可以中间临时图像并复制生成的内容最终docker图像。另外,npm应该是docker映像的一部分,创建一个npm映像,并在最终的docker映像中用作构建器映像。