87

Up until recently, when one was doing docker-compose up for a bunch of containers and one of the started containers stopped, all of the containers were stopped. This is not the case anymore since https://github.com/docker/compose/issues/741 and this is a really annoying for us: We use docker-compose to run selenium tests which means starting application server, starting selenium hub + nodes, starting tests driver, then exiting when tests driver stops.

Is there a way to get back old behaviour?

Kolay.Ne
  • 1,345
  • 1
  • 8
  • 23
insitu
  • 4,488
  • 3
  • 25
  • 42

4 Answers4

173

You can use:

docker-compose up --abort-on-container-exit

Which will stop all containers if one of your containers stops

Metalstorm
  • 2,940
  • 3
  • 26
  • 22
  • 6
    I'm not sure if this is _the_ way to do it, but it certainly works and even carries over the exit code of the stopped container. Pretty neat feature for integration tests. – JohnEye Oct 17 '18 at 17:28
  • Does not work in detached mode - "-d" though. Would love something like this so that if one container fails, Docker shuts down all its dependent containers as well. – Parth Patel Jan 27 '21 at 19:22
  • 2
    To make sure the exit code corresponds with the exit code of the test container use the `--exit-code-from` command line option. See https://stackoverflow.com/a/43367250/11567551 for details and links. – Michiel Leegwater May 25 '22 at 14:07
18

In your docker compose file, setup your test driver container to depend on other containers (with depends_on parameter). Your docker compose file should look like this:

services:
  application_server:
     ...
  selenium:
     ...
  test_driver:
    entry_point: YOUR_TEST_COMMAND
    depends_on:
      - application_server
      - selenium

With dependencies expressed this way, run:

docker-compose run test_driver

and all the other containers will shut down when the test_driver container is finished.



This solution is an alternative to the docker-compose up --abort-on-container-exit answer. The latter will also shut down all other containers if any of them exits (not only the test driver). It depends on your use case which one is more adequate.

Jakub Kukul
  • 12,032
  • 3
  • 54
  • 53
  • 3
    This suggested approach did not work for me. docker-compose version docker-compose version 1.22.0, build f46880f docker-py version: 3.4.1 CPython version: 3.6.4 OpenSSL version: OpenSSL 1.0.2o 27 Mar 2018 – Chaim Geretz Oct 08 '18 at 21:25
  • 17
    Didn't work for me neither. The 'depends_on' containers are started before the main container starts, but they aren't stopped after the main container stops. – Tobias Uhmann Apr 16 '19 at 12:27
  • 2
    This works great for adhoc runs (i.e. tests. Yes it doesn't close other containers but for integration tests, the entire environment is discarded after running tests so that sort of cleanup doesn't matter. This [section](https://docs.docker.com/compose/faq/#whats-the-difference-between-up-run-and-start) on docker docs was helpful in explaining the difference between three – Govind Rai Sep 23 '20 at 21:35
7

Did you try the work around suggested on the link you provided?

Assuming your test script looked similar to this:

$ docker-compose rm -f
$ docker-compose build
$ docker-compose up --timeout 1 --no-build

When the application tests end, compose would exit and the tests finish.

In this case, with the new docker-compose version, change your test container to have a default no-op command (something like echo, or true), and change your test script as follows:

$ docker-compose rm -f
$ docker-compose build
$ docker-compose up --timeout 1 --no-build -d
$ docker-compose run tests test_command...
$ docker-compose stop

Using run allows you to get the exit status from the test run, and you only see the output of the tests (not all the dependencies).

Reference

If this is not acceptable, you could refer to Docker Remote API and watch for the stop event for the containers and act on it.

An example usage is this docker-gen tool written in golang which watches for container start events, to automatically regenerate configuration files.

Vincent De Smet
  • 4,859
  • 2
  • 34
  • 41
  • Thanks a lot for the great tip. No, I did not try yet the suggested workaround and to be honest with you I read the link not carefully enough to understand I had a workaround in front of me! I will try that asap. – insitu Nov 19 '15 at 16:02
  • 1
    Another important thing to know: sadly the `docker-compose run foo` command doesn't set aliases of your `foo` service (docker-compose 1.8.0-rc1). See https://github.com/docker/compose/issues/3492#issuecomment-230931596 – jineff Jul 19 '16 at 09:14
-2

I'm not sure this is the perfect answer to your problem, but maestro for Docker, lets you manage mulitple Docker containers as single unit.

It should feel familiar as you group them using a YAML file.

taco
  • 1,367
  • 17
  • 32