如何让Gitlab CI/CD运行带有一些自定义变量的容器?

How to make Gitlab CI/CD run container with some custom variables?

提问人:Stanly T 提问时间:2/4/2021 更新时间:2/6/2021 访问量:4186

问:

我有一份在 GitLab CI/CD 上启动 android UI 测试的工作。它以某种方式从注册表中的映像运行容器。我不知道 Gitlab CI/CD 使用命令“docker run ...”在哪里以及如何运行该映像,但我需要扩展该命令,并且我想在此命令中传递一些变量(或参数)。android-uitests:1.0

下面是我希望 Gitlab 执行的命令示例:

docker run -d \
       -t \
       --privileged \
       -e "SNAPSHOT_DISABLED"="true" \
       -e "QTWEBENGINE_DISABLE_SANDBOX"=1 \
       -e "WINDOW"="true" \
       --volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" \
       -p 5555:5555 -p 5554:5554 -p 5901:5901 \
       --name emulator \
       android-uitest:1.0

这是一个舞台,它与图像有关

ui-tests:
  image: registry.myproject:5000/android-uitests:1.0
  stage: ui-tests
  only:
    - merge_requests
    - schedules
  when: manual
  script:
    - bash /run-emulator.sh
    - adb devices
    - adb shell input keyevent 82
    - adb shell settings put global window_animation_scale 0 &
    - adb shell settings put global transition_animation_scale 0 &
    - adb shell settings put global animator_duration_scale 0 &
    - ./gradlew mobile:connectedDevDebugAndroidTest -Pandroid.testInstrumentationRunnerArguments.package=app.online.tests.uitests
  tags:
    - androidtest

所以换句话说,我想配置运行我的映像的“引擎盖下命令”。docker run

请告诉我该怎么做?

docker 持续集成 gitlab

评论

0赞 takharsh 3/12/2023
你有没有找到任何解决方案来在运行图像时在 Gitlab 中传递参数?

答:

2赞 Gruber 2/6/2021 #1

考虑到您使用的是 Docker 容器,我假设您在 Docker 执行器模式下使用 Gitlab Runner,这意味着当您不指定 docker 映像来运行 CI 作业时,您实际上是在运行与此类似的脚本

image: docker:19.03.13

variables:
  DOCKER_TLS_CERTDIR: "/certs"

services:
  - docker:19.03.13-dind

script:
  - (your commands)

为了理解发生了什么,让我们分几个步骤来分解它:

    image: docker:19.03.13
(...)
    services:
      - docker:19.03.13-dind

docker-19.03.13-dind,和 有什么不一样?docker:19.03.13

为什么它是服务而不是图像?

DIND 的意思是 Docker-in-Docker,Gitlab 文档的这一部分可以在进一步的技术细节中解释它,但从这一部分需要了解的是 Gitlab 的 CI 上下文中的服务是什么,以及为什么他们必须在已经使用 Docker 镜像作为默认环境时指定额外的 Docker 镜像。当你在 Gitlab CI 上编写时,你可以在现有容器中使用它的命令例如,当您想要将 PostgreSQL(数据库)容器连接到您正在构建的后端容器时,但无需设置 docker-compose 或多个容器。service

使用 docker 服务与 docker 镜像一起运行,这意味着您可以直接在作业中使用,而无需任何额外的设置。前面的 StackOverflow 问题进一步解释了这个问题。docker run

返回到代码,而不是直接将注册表映像部署为作业:

ui-tests:
  image: registry.myproject:5000/android-uitests:1.0

您可能需要首先构建容器并将其上传到注册表:

image: docker:19.03.12

services:
  - docker:19.03.12-dind

variables:
  # Use TLS https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#tls-enabled
  DOCKER_HOST: tcp://docker:2376
  DOCKER_TLS_CERTDIR: "/certs"

before_script:
  - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
  - docker build $CI_REGISTRY_IMAGE:latest --tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA --tag $CI_REGISTRY_IMAGE:latest .
  - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
  - docker push $CI_REGISTRY_IMAGE:latest

此代码片段将在存储库的根文件夹中构建 Dockerfile,并将其上传到 Gitlab 私有(或公共,如果项目设置为公共)镜像注册表。现在,您可以指定一个额外的作业来专门执行您想要的操作:

最终示例

image: docker:19.03.12
stages:
  - build
  - release
services:
  - docker:19.03.12-dind

variables:
  # Use TLS https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#tls-enabled
  DOCKER_HOST: tcp://docker:2376
  DOCKER_TLS_CERTDIR: "/certs"

before_script:
  - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY

build:
  stage: build
  script:
    - docker pull $CI_REGISTRY_IMAGE:latest || true
    - docker build --cache-from $CI_REGISTRY_IMAGE:latest --tag $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA --tag $CI_REGISTRY_IMAGE:latest .
    - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
    - docker push $CI_REGISTRY_IMAGE:latest

deploy:
  stage: release
  script:
    - docker pull $CI_REGISTRY_IMAGE:latest || true
    - docker run -d -t --privileged -e "SNAPSHOT_DISABLED"="true" -e "QTWEBENGINE_DISABLE_SANDBOX"=1    -e "WINDOW"="true" --volume="/tmp/.X11-unix:/tmp/.X11-unix:rw"    -p 5555:5555 -p 5554:5554 -p 5901:5901 --name emulator $CI_REGISTRY_IMAGE:latest

你为什么使用 ?$VARIABLES

如果环境变量听起来可能令人困惑,这里是 Gitlab 为其创建的每个作业生成的默认环境变量列表

我引用的最后一个示例将导致 Docker 容器在注册执行器的同一台机器上运行,并使用您指定的环境变量。

如果你需要一个实际的例子,你可以用我一个项目的这个gitlab-ci.yml作为参考

评论

1赞 Stanly T 2/6/2021
非常感谢您如此详细的回答