当测试容器完成时终止 docker 组合

Terminate docker compose when test container finishes

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

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

但似乎容器并没有在完​​成量角器测试后终止。

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

如何在测试完成后让compose结束成功或失败?

# 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}"

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

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

有关详细信息,请参阅


原答案

与此 类似,您需要 运行 将测试作为一个独立的任务来报告退出状态给您的 CI。

您可以将 test-运行ner 分离到它自己的 yaml 中或修改 test-运行ner 以默认为无操作 command/entrypoint.

分开测试运行ner

单独指定 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

没有op测试运行ner

默认 test-runner 为无操作 entrypoint/command 然后手动 运行 测试命令

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

Return 代码

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

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

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

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

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

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

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 $?

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

--abort-on-container-exit 停止所有容器 停止了。

--exit-code-from Return 所选服务的退出代码 容器。

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

version: '2.3'

services:
  elasticsearch:
    ...
  service-api:
    ...
  service-test:
    ...
    depends_on:
      - elasticsearch
      - service-api

以下命令确保 elasticsearchservice-apiservice-test 完成后关闭,并且 returns 来自 service-test 容器的退出代码:

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

为了避免使用单独的配置文件,您可以更新 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会触发相关服务的启动。

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

Case-1: docker-compose up -d

您可以使用 docker-compose up -d,用 test-runner 测试它,然后用 docker-compose down 终止,但是当您使用 docker-compose up -d 时的问题是 你不会再看到标准输出的日志

案例 2:docker-从服务中编写 --exit-code-

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

One of the solution to see the logs before terminating them is using --tail=1000 -f

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

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