我有一个Python程序,它使用Docker Python SDK为第三方Docker映像运行容器。在我的代码中有这样的东西:
import docker
docker.from_env().containers.run(image="<other_image>")
我的程序也打包在Docker中,我想用gitlab CI进行测试。所以我的.gitlab-ci.yml
看起来是这样的:
image: <my_image>:latest
stages:
- Tests
pytest:
stage: Tests
script:
- pytest
测试涵盖了上面的python代码。问题是CI在具有docker.errors.DockerException: Error while fetching server API version: ('Connection aborted.', FileNotFoundError(2, 'No such file or directory'))
的docker.from_env()
上失败。
我认为这是因为在<my_image>
容器中没有可访问的docker服务器。我寻找解决方案,我找到了docker:dind
one+;暴露码头插座";即/var/run/docker.sock:/var/run/docker.sock
一个,但我无法使它工作。
我为docker:dind
找到的所有例子都是直接在.gitlab-ci.yml
中调用docker的,但我没有发现任何例子可以解释如何利用它在自己的代码中使用docker SDK。此外,套接字解决方案要求您更改gitlab runner配置,但我无法访问它(我使用的是gitlab免费帐户,没有机会托管我自己的runner(。
我需要的基本上是:
image:
name: <my_image>:latest
volumes:
- /var/run/docker.sock:/var/run/docker.sock
但AFAIK它并不存在。
有什么解决办法吗?
更新:我意识到这实际上是可行的:
image: docker
services:
- docker:dind
stages:
- Tests
pytest:
stage: Tests
script:
- docker run -v /var/run/docker.sock:/var/run/docker.sock <my_image>:latest pytest
但我仍然很想知道是否可以在仍然使用我的映像作为基础的情况下进行此操作(例如,也许我不想在映像中安装pytest,但我会在.gitlab-ci.yml
中使用before_script
指令进行此操作……我也可以在要执行的脚本中进行此操作,而不是直接运行pytest,所以我同意这可能不是一个很好的理由(。
您应该能够做到这一点:
image: <your python/docker-SDK image>
pytest:
services:
- docker:dind
variables:
DOCKER_TLS_CERTDIR: ""
DOCKER_HOST: tcp://docker:2375
script:
- pytest
与常规的docker
一样,SDK将使用这些环境变量来正确配置客户端以使用docker:dind
服务。