【问题标题】:Terminate docker compose when test container finishes测试容器完成时终止 docker compose
【发布时间】:2017-04-15 22:22:53
【问题描述】:

我目前正在运行一个 docker-compose 堆栈,用于与量角器测试运行器、服务于网页的 nodejs 服务器和服务于 java 后端的 Wildfly 服务器的基本集成测试。

堆栈是从我的构建服务器(concourse ci)中的一个dind(docker in docker)容器运行的。

但似乎容器不会在完成量角器测试时终止。

因此,由于 wildfly 和 nodejs 的容器仍在运行,构建任务永远不会完成......

测试完成后如何让作曲以成功或失败告终?

# Test runner
test-runner:
  image: "${RUNNER_IMG}"
  privileged: true
  links:
    - client
    - server
  volumes:
  - /Users/me/frontend_test/client-devops:/protractor/project
  - /dev/shm:/dev/shm
  entrypoint:
    - /entrypoint.sh
    - --baseUrl=http://client:9000/dist/
    - /protractor/conf-dev.js
    - --suite=remember
# Client deployment
client:
  image: "${CLIENT_IMG}"
  links:
    - server
# Server deployment
server:
  image: "${SERVER_IMG}"

【问题讨论】:

    标签: docker docker-compose concourse


    【解决方案1】:

    Compose 已将 --exit-code-from {container} 标志添加到 docker-compose up,这使得这更容易。

    docker-compose up --exit-code-from test-runner
    

    更多详情请参阅Michael Spector's answer


    原答案

    rspec q/a 类似,您需要将测试作为独立任务运行,将退出状态报告回您的 CI。

    您可以将测试运行程序分离到它自己的 yaml 中,或者将测试运行程序修改为默认为无操作命令/入口点。

    分离测试运行器

    单独指定 test-runner 配置(您可能需要升级到 version 2 networks 而不是使用 links 才能跨多个撰写文件工作)。

    docker-compose up -d
    docker-compose -f test-runner.yml run test-runner
    rc=$?
    docker-compose down
    exit $rc
    

    没有操作测试运行器

    默认test-runner 为无操作入口点/命令,然后手动运行测试命令

    services:
      test-runner:
        image: "${RUNNER_IMG}"
        command: 'true'
    

    然后

    docker-compose up -d
    docker-compose run test-runner /launch-tests.sh
    rc=$?
    docker-compose down
    exit $rc
    

    返回码

    如果您的 CI 具有“发布任务”的概念,您可能可以跳过 rc 捕获并在 test-runner CI 任务完成后运行 docker-compose down。您的 CI 也可能会为您清理容器。

    【讨论】:

    • 是否可以在docker-compose文件中写入--exit-code-from test-runner之类的东西?
    • @SerhiiKushchenko 在spec 中没有像exit-code-from 这样的东西
    【解决方案2】:

    我已经尝试了本次讨论中提供的解决方案,但问题仍然存在

    案例一:docker-compose up -d

    您可以使用docker-compose up -d,通过test-runner 对其进行测试,然后通过docker-compose down 终止,但使用docker-compose up -d 时的问题是您不会看到日志 不再是标准输出了。

    案例 2:docker-compose up --exit-code-from a service

    如果您使用--exit-code-from <service> 表示--abort-on-container-exit,则可以view the docker logs,但成功时服务不会发送退出命令。然后您需要捕获您的容器在发送docker-compose down 以阻止它们之前完成测试。

    在终止它们之前to see the logs 的一个解决方案是使用--tail=1000 -f

    docker-compose up -d
    docker-compose logs --tail=1000 -f test-runner
    docker-compose down
    exit $rc
    

    还有一个使用nohup的解决方案,但是你需要等到过程完全完成然后打开输出日志文件,所以上面应该更容易

    【讨论】:

      【解决方案3】:

      为避免使用单独的配置文件,您可以更新 docker-compose 配置以使用 depends_on 选项引入服务之间的依赖关系,该选项可用于版本 2 及更高版本。因此,test-runner 的启动将启动客户端的运行。

      请注意,如果您需要等待一段时间才能从您正在测试的内部服务启动实际的 Web 服务器,您可以使用 wait-for-it.sh 脚本等待服务器可用。

      # Test runner
      test-runner:
        image: "${RUNNER_IMG}"
        privileged: true
        links:
          - client
          - server
        volumes:
        - /Users/me/frontend_test/client-devops:/protractor/project
        - /dev/shm:/dev/shm
        depends_on:
          - client
        entrypoint:
          - wait-for-it.sh
          - client
          - -t
          - '180'
          - --
          - /entrypoint.sh
          - --baseUrl=http://client:9000/dist/
          - /protractor/conf-dev.js
          - --suite=remember
      # Client deployment
      client:
        image: "${CLIENT_IMG}"
        depends_on:
          - server
        links:
          - server
      # Server deployment
      server:
        image: "${SERVER_IMG}"
      

      更新配置后,简单的docker-compose up test-runner会触发相关服务的启动。

      【讨论】:

        【解决方案4】:

        您可以使用这些 docker-compose 参数来实现:

        --abort-on-container-exit 如果有任何容器停止运行,则停止所有容器 停止了。

        --exit-code-from返回所选服务的退出码 容器。

        例如,有这个docker-compose.yml:

        version: '2.3'
        
        services:
          elasticsearch:
            ...
          service-api:
            ...
          service-test:
            ...
            depends_on:
              - elasticsearch
              - service-api
        

        以下命令确保elasticsearchservice-apiservice-test 完成后下线,并从service-test 容器返回退出代码:

        docker-compose -f docker-compose.yml up \
            --abort-on-container-exit \
            --exit-code-from service-test
        

        【讨论】:

        • 非常感谢您阅读了一半的互联网以找到您的解决方案:-)
        • 同意,这很难搜索
        • 确实如此。已加星标和投票以确保它不会再次丢失。
        • 非常...微不足道的答案。我希望这个答案能长到顶部,所以每个人都不会在搜索时丢失它。
        • 不错的答案!顺便说一句,你可以省略 --abort-on-container-exit docs.docker.com/compose/reference/up
        【解决方案5】:

        您可以在 Concourse 的任务步骤中使用 ensure 执行清理任务。 https://concourse-ci.org/ensure-step.html

        在您的情况下,您可以在量角器测试之后添加一个ensure 块,并运行一个任务来拆除之前docker-compose 的内容。您还可以使用on-success 步骤https://concourse-ci.org/on-success-step.html 进行拆卸,如果您的测试失败,将保留docker-compose'd 容器。

        【讨论】:

          【解决方案6】:

          我发现最优雅的解决方案是在您的docker-compose.yml 文件中使用depends_on

          services:
            dynamodb:
            ...
            test_runner:
              ...
              depends_on:
                - dynamodb
          

          现在您可以使用docker-compose run --rm test_runner,它将设置您的依赖项、运行您的测试、拆除所有内容并传播返回代码。

          docker-compose run test_runner false
          Starting test_dynamodb_1 ... done
          echo $?
          1
          docker-compose run test_runner true
          Starting test_dynamodb_1 ... done
          echo $?
          

          【讨论】:

          • 不知道为什么这没有得到更多的支持 - 在我看来,它比公认的答案更好地解决了这个问题。
          • 请注意,与stackoverflow.com/a/49485880/51197 相比,这不会破坏依赖关系
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-01-05
          • 2023-03-09
          • 2023-04-11
          • 1970-01-01
          • 1970-01-01
          • 2020-02-09
          • 1970-01-01
          相关资源
          最近更新 更多