在 .gitlab-ci.yml 中运行 docker-compose build

Posted

技术标签:

【中文标题】在 .gitlab-ci.yml 中运行 docker-compose build【英文标题】:Run docker-compose build in .gitlab-ci.yml 【发布时间】:2017-02-13 13:38:10 【问题描述】:

我有一个.gitlab-ci.yml 文件,其中包含以下内容:

image: docker:latest

services:
  - docker:dind

before_script:
  - docker info
  - docker-compose --version

buildJob:
  stage: build
  tags:
    - docker
  script:
    - docker-compose build

但是在ci-log我收到消息:

$ docker-compose --version
/bin/sh: eval: line 46: docker-compose: not found

我做错了什么?

【问题讨论】:

【参考方案1】:

编辑我添加了另一个答案,为支持 docker-compose 的 .gitlab-ci.yml 配置提供了一个最小示例。


docker-compose 可以作为 Python 包安装,该包不随您的图像一起提供。您选择的图像甚至没有提供 Python 的安装:

$ docker run --rm -it docker sh
/ # find / -iname "python"
/ # 

寻找 Python 会得到一个空的结果。所以你必须选择一个不同的镜像,它适合你的需求,最好安装 docker-compose 或者你自己创建一个。

您选择的 docker 映像使用 Alpine Linux。如果您不熟悉 Alpine Linux,您可以将其用作您自己的镜像的基础,或者先尝试其他镜像。

我遇到了同样的问题,我在公共 GitHub 存储库中创建了一个 Dockerfile,并将它与我的 Docker Hub 帐户连接起来,并选择了一个自动构建来在每次推送到 GitHub 存储库时构建我的图像。然后,您可以使用 GitLab CI 轻松访问自己的图像。

【讨论】:

您可以删除其中一个答案吗?很困惑地找到两个,加上很多“编辑”消息。 (如果需要,我们可以查看编辑历史记录)。【参考方案2】:

如果您不想提供预安装了 docker-compose 的自定义 docker 映像,则可以通过在构建期间安装 Python 来使其正常工作。安装 Python 后,您终于可以安装 docker-compose 以启动容器了。

image: docker:latest

services:
- docker:dind

before_script:
- apk add --update python py-pip python-dev && pip install docker-compose # install docker-compose
- docker version
- docker-compose version

test:
  cache:
    paths:
    - vendor/
  script:
  - docker-compose up -d
  - docker-compose exec -T php-fpm composer install --prefer-dist
  - docker-compose exec -T php-fpm vendor/bin/phpunit --coverage-text --colors=never --whitelist src/ tests/

如果您收到此错误或类似错误,请使用 docker-compose exec-T

$ docker-compose exec php-fpm composer install --prefer-dist
Traceback (most recent call last):
  File "/usr/bin/docker-compose", line 9, in <module>
    load_entry_point('docker-compose==1.8.1', 'console_scripts', 'docker-compose')()
  File "/usr/lib/python2.7/site-packages/compose/cli/main.py", line 62, in main
    command()
  File "/usr/lib/python2.7/site-packages/compose/cli/main.py", line 114, in perform_command
    handler(command, command_options)
  File "/usr/lib/python2.7/site-packages/compose/cli/main.py", line 442, in exec_command
    pty.start()
  File "/usr/lib/python2.7/site-packages/dockerpty/pty.py", line 338, in start
    io.set_blocking(pump, flag)
  File "/usr/lib/python2.7/site-packages/dockerpty/io.py", line 32, in set_blocking
    old_flag = fcntl.fcntl(fd, fcntl.F_GETFL)
ValueError: file descriptor cannot be a negative integer (-1)
ERROR: Build failed: exit code 1

【讨论】:

不是一般的方式,其实可以得到“apk: command not found” 这不再有效,可能是因为更新的 docker 镜像。现在pythonpython-dev不再是有效的apk包添加,然后当你指定python2时,gcc不知何故丢失了【参考方案3】:

我创建了一个简单的 docker 容器,它在 docker:latest 之上安装了 docker-compose。见https://hub.docker.com/r/tmaier/docker-compose/

您的.gitlab-ci.yml 文件如下所示:

image: tmaier/docker-compose:latest

services:
  - docker:dind

before_script:
  - docker info
  - docker-compose --version

buildJob:
  stage: build
  tags:
    - docker
  script:
    - docker-compose build

【讨论】:

在 gitlab ci error: command 'gcc' failed with exit status 1 中得到这个错误【参考方案4】:

关注official documentation:

# .gitlab-ci.yml
image: docker
services:
  - docker:dind    
build:
  script:
    - apk add --no-cache docker-compose
    - docker-compose up -d

示例 docker-compose.yml:

version: "3.7"
services:
  foo:
    image: alpine
    command: sleep 3
  bar:
    image: alpine
    command: sleep 3

我们个人不再遵循此流程,因为您失去了对正在运行的容器的控制,它们最终可能会无休止地运行。这是因为 docker-in-docker 执行器。我们开发了一个 python 脚本作为解决方法来杀死我们 CI 中的所有旧容器,can be found here。但我不建议再像这样启动容器了。

【讨论】:

@tmaier 我想我也被困在这里了。您使用了哪种“Runner-Installation”?我的意思是你走的三种方式中的哪一种? docs.gitlab.com/ee/ci/docker/… 我们正在使用 docker-in-docker 执行器docs.gitlab.com/ee/ci/docker/… 虽然这可行,但这意味着在每个构建时都需要安装(并获取...)docker-compose,因此它会增加构建时间。如果您有多个需要 docker-compose 的作业(并且在生产场景中您可能会这样做),构建时间将大大增加。 如果您想更频繁地使用它,您可以使用包含在线三行的小型 Dockerfile 为您的 CI 定义自己的 docker 映像:` FROM alpine \n RUN apk add --no-cache py -pip && pip install docker-compose ` 但请记住要始终保持此映像是最新的 非常感谢您的回答。我只是有网络问题。似乎没有容器可以与另一个容器通信……这种情况下只有我一个吗? (使用共享跑步者)【参考方案5】:

Docker还提供了一个官方镜像:docker/compose

如果您不想在每条管道上都安装它,这是理想的解决方案。

请注意,在最新版本的 GitLab CI/Docker 中,您可能需要授予对 GitLab CI Runner 的特权访问权限并配置/禁用 TLS。见Use docker-in-docker workflow with Docker executor

variables:
  DOCKER_HOST: tcp://docker:2375/
  DOCKER_DRIVER: overlay2

# Official docker compose image.
image:
  name: docker/compose:latest

services:
  - docker:dind

before_script:
  - docker version
  - docker-compose version

build:
  stage: build
  script:
    - docker-compose down
    - docker-compose build
    - docker-compose up tester-image

请注意,在 docker-compose earlier than 1.25 的版本中:

由于图像使用docker-compose-entrypoint.sh 作为入口点,您需要在.gitlab-ci.yml 中将override it 返回到/bin/sh -c。否则,您的管道将失败并显示No such command: sh

    image:
      name: docker/compose:latest
      entrypoint: ["/bin/sh", "-c"]

【讨论】:

这可行,但正如您的链接源所说,它需要一个 GitLab *9.4**+ ,因为您**需要覆盖 CI yaml 中的入口点。 @webmaster777 执行到“docker-compose 版本”时出现此错误...Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running? ERROR: Job failed: exit code 1...我该如何解决? 只有在我添加变量DOCKER_HOST: tcp://docker:2375/DOCKER_DRIVER: overlay2时才有效 有效!如果涉及绑定挂载或卷,则还需要一些环境变量——DOCKER_HOST=tcp://docker:2375DOCKER_DRIVER=overlay2(可选)——指示 docker 与服务内部启动的守护进程(docker:dind)进行对话。更多信息请参考Use docker-in-docker executor。 即使设置了所有变量,这对我(共享的 gitlab.com 跑步者)仍然不起作用,Cannot connect to the Docker daemon at tcp://docker:2375/. Is the docker daemon running?【参考方案6】:

Alpine linux 现在在其“edge”分支中有一个 docker-compose 包,因此您可以在 .gitlab-ci.yml 中以这种方式安装它


a-job-with-docker-compose:
  image: docker
  services:
    - docker:dind
  script:
    - apk add docker-compose --update-cache --repository http://dl-3.alpinelinux.org/alpine/edge/testing/ --allow-untrusted
    - docker-compose -v

【讨论】:

不工作..需要更新答案..运行时docker-compose 抛出pkg_resources.DistributionNotFound: The 'docker-compose==1.24.0' distribution was not found and is required by the application【参考方案7】:

我认为上面的大部分内容都很有帮助,但是我需要将它们共同应用来解决这个问题,下面是对我有用的脚本

我希望它也对你有用

另外请注意,在您的 docker compose 中,这是您必须为图像名称提供的格式

&lt;registry base url&gt;/&lt;username&gt;/&lt;repo name&gt;/&lt;image name&gt;:&lt;tag&gt;

image:
  name: docker/compose:latest
  entrypoint: ["/bin/sh", "-c"]

variables:
  DOCKER_HOST: tcp://docker:2375/
  DOCKER_DRIVER: overlay2

services:
  - docker:dind

stages:
- build_images

before_script:
  - docker version
  - docker-compose version
  - docker login -u $CI_REGISTRY_USER -p $CI_JOB_TOKEN $CI_REGISTRY

build:
  stage: build_images
  script:
    - docker-compose down
    - docker-compose build
    - docker-compose push

【讨论】:

【参考方案8】:

我真的花了一些时间才让它与 Gitlab.com 共享跑步者一起工作。

我想说“使用 docker/compose:latest 就是这样”,但不幸的是我无法让它工作,即使设置了所有 env 变量,我也会收到 Cannot connect to the Docker daemon at tcp://docker:2375/. Is the docker daemon running? 错误。

我也不喜欢安装五千个依赖项以通过 pip 安装 docker-compose 的选项。

幸运的是,对于最近的 Alpine 版本(3.10+),Alpine 存储库中有 docker-compose 包。这意味着@n2o 的answer 可以简化为:

test:
  image: docker:19.03.0

  variables:
    DOCKER_DRIVER: overlay2
    # Create the certificates inside this directory for both the server
    # and client. The certificates used by the client will be created in
    # /certs/client so we only need to share this directory with the
    # volume mount in `config.toml`.
    DOCKER_TLS_CERTDIR: "/certs"

  services:
    - docker:19.03.0-dind

  before_script:
    - apk --no-cache add docker-compose      # <---------- Mind this line
    - docker info
    - docker-compose --version

  stage: test
  script:
      - docker-compose build

这对我来说从第一次尝试就完美了。也许其他答案没有的原因是在 Gitlab.com 共享跑步者的某些配置中,我不知道......

【讨论】:

这真的是 2021 年的解决方案,所有其他人都没有使用自定义跑步者【参考方案9】:

tiangolo/docker-with-compose 有效:

image: tiangolo/docker-with-compose

stages:
  - build
  - test
  - release
  - clean

  
before_script:
  - docker login -u gitlab-ci-token -p $CI_BUILD_TOKEN registry.gitlab.com

build:
  stage: build
  script:
    - docker-compose -f docker-compose-ci.yml build --pull 


test1:
    stage: test
    script:
        - docker-compose -f docker-compose-ci.yml up -d
        - docker-compose -f docker-compose-ci.yml exec -T php ...

【讨论】:

这对我不起作用。我收到“连接期间出错:发布docker:2375/v1.40/auth:拨打tcp:在169.254.169.254:53 上查找docker:没有这样的主机”。然而,webmaster777 的解决方案对我有用,并且似乎是最好的解决方案,因为创建 tiangolo/docker-with-compose 的主要原因是因为 docker/compose 之前存在入口点问题。既然这不是问题,我认为这可能不再是一个好的解决方案。

以上是关于在 .gitlab-ci.yml 中运行 docker-compose build的主要内容,如果未能解决你的问题,请参考以下文章

gitlab-ci.yml、before_script 和 artifact

获取使用 .gitlab-ci.yml 运行的 Windows Docker 容器

Gitlab-ci.yml 创建合并请求

如何使用 gitlab-ci.yml 在 gitlab 中更新 JSON 文件的内容?

如何在gitlab-ci.yml中将文件从存储库复制到用于作业的docker容器中

从 Jenkins Ci 服务迁移到 gitlab-ci.yml