当测试容器完成时终止docker compose

gt0wga4j  于 2023-04-20  发布在  Docker
关注(0)|答案(7)|浏览(131)

我目前正在运行一个docker-compose堆栈,用于基本的集成测试,使用一个量角器测试运行器,一个nodejs服务器服务于网页,一个wildfly服务器服务于java后端。
这个堆栈是从我的构建服务器(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}"
aiazj4mn

aiazj4mn1#

你可以使用这些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
cbjzeqam

cbjzeqam2#

Compose在docker-compose up中添加了--exit-code-from {container}标志,这使得这更容易。

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

请参阅Michael Spector's answer了解更多详细信息。

原始应答

与此rspec q/a类似,您需要将测试作为独立任务运行,并将退出状态报告给CI。
您可以将test-runner分离到它自己的yaml中,或者修改test-runner以默认为no op命令/入口点。

分离测试运行器

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

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

无op测试运行器

test-runner默认为no op entrypoint/命令,然后手动运行test命令

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有“post tasks”的概念,您可能可以跳过rc捕获,而在test-runner CI任务完成后运行docker-compose down。您的CI也可能会为您清理容器。

fcy6dtqo

fcy6dtqo3#

我发现最优雅的解决方案是在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 $?
13z8s7eq

13z8s7eq4#

我已经尝试了这次讨论中提出的解决办法,但问题仍然存在

Case-1: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,但服务不会在成功时发送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的解决方案,但您需要等到进程完全完成,然后打开输出日志文件,因此上面的操作应该更简单。

bjg7j2ky

bjg7j2ky5#

我的docker compose up有一些标志组合(--build),可以防止在--abort-on-container-exit触发时停止所有服务容器。
例如:

docker compose up \
  --build service1 \
  --attach service1 --attach service2 \
  --abort-on-container-exit

将启动service1service2,但只会在中止时停止service1,因为就Docker而言,它只负责构建service1,并且拒绝假设service2不是预先存在的-即使它是,你知道,在同一个docker-compose.yml中定义并与depends_on链接,* 它只是启动它。* 它只是让service2运行。1
要解决这个问题,我需要做的就是确保在docker compose up之后运行docker compose down
这可以使用trap来完成,以确保它始终运行,即使docker compose up失败并提前退出脚本:

#!/usr/bin/env sh

cleanup() {
  docker compose down
}
trap cleanup EXIT  # will always run when the script exits

docker compose up \
  --build service1 \
  --attach service1 --attach service2 \
  --abort-on-container-exit

脚注

1:这对我来说是个问题,因为我的service1期望它的service2处于新鲜状态。

aiqt4smr

aiqt4smr6#

为了避免单独的配置文件,您可以更新docker-compose配置,通过depends_on选项引入服务之间的依赖关系,从版本2 format开始提供。因此,启动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将触发相关服务的启动。

ef1yzkbh

ef1yzkbh7#

您可以在Concourse中的任务步骤上使用ensure执行清理任务。https://concourse-ci.org/ensure-step.html
在你的例子中,你可以在量角器测试后添加一个ensure块,然后运行一个任务来拆除之前docker-compose的东西。你也可以使用on-success步骤https://concourse-ci.org/on-success-step.html来执行拆除,如果测试失败,docker-compose的容器将被保留。

相关问题