Terminate docker compose when test container finishes

Compose has added the --exit-code-from {container} flag to docker-compose up which makes this easier.

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

See Michael Spector's answer for more detail.


Original Answer

Similar to this rspec q/a, you need to run the tests as a standalone task that report an exit status back to your CI.

You could separate the test-runner into it's own yaml or modify the test-runner to default to a no op command/entrypoint.

Separate the test runner

Specify the test-runner config separately (You might need to upgrade to version 2 networks instead of using links to work across multiple compose files).

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

No op test runner

Default the test-runner to a no op entrypoint/command and then manually run the test command

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

Then

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

Return codes

If your CI has the concept of "post tasks" you might be able to skip the rc capturing and just run the docker-compose down after the test-runner CI task has completed. It's also possible your CI cleans up the containers for you.


You can use these docker-compose parameters to achieve that:

--abort-on-container-exit Stops all containers if any container was stopped.

--exit-code-from Return the exit code of the selected service container.

For example, having this docker-compose.yml:

version: '2.3'

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

The following command ensures that elasticsearch and service-api go down after service-test is finished, and returns the exit code from the service-test container:

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