提问人:Stanly T 提问时间:2/4/2021 更新时间:2/6/2021 访问量:4186
如何让Gitlab CI/CD运行带有一些自定义变量的容器?
How to make Gitlab CI/CD run container with some custom variables?
问:
我有一份在 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 容器,我假设您在 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
作为参考。
评论