Parallel execution of `docker-compose up` commands with same configuration

The use case I have is I am running application tests that require services running in docker, those tests are running in separate processes (JVM/Scala/ScalaTest) and I would like the test running processes to be able to start the docker compose config they need or just use the one they need if it is started already.

Issue is that those processes running tests are started in parallel and they can execute docker-compose up on same config simultaneously, which sometimes works fine, sometimes one of the processes throws an error about resources already being in use, and sometimes the deployment gets put in an error state where it seems that one command creates containers first where other command creates network first and it fails to start all together because of naming conflict errors. It seems like there is no way to do what I am trying to do without some kind of external mechanism to make the execution sequential or just starting all of the composes before the tests, and I would really like to avoid both of these solutions.

Is there a way to do this? Could docker compose be improved to support this kind of behavior?

I am not sure if I really understood everything completely.

You might want to check whether depends_on might help. The long syntax allows waiting until a specific container is healthy (of course this container then needs to implement a health check for everything to work properly)

I also get the feeling that providing a project name might solve your problems.

Or if your tests are unit tests, I am quite sure you could leverage test containers to control the containers from within your unit test. If I remember right, Scala should be able to use Java Libraries as well.

Yeah, I think you misunderstood me. A simplest case of what am I trying to do is that imagine that you have two processes that run their own programs that use a docker compose and they themselves want to bring that compose up. It might be the same compose and they might call a docker-compose up on the same config simultaneously, in parallel. It works unpredictable - sometimes it causes issues that I have described.

I know of workarounds, like starting a compose before running those processes or creating some another wrapper program that would be called instead of compose and it would take care of making docker-compose up sequential. I just wonder if it was somehow possible to not need these workarounds, if docker compose could be made to not throw errors in such use case.

I think this might be the underlying issue - The docker daemon API lets you create two networks with the same name · Issue #18864 · moby/moby · GitHub. Somehow multiple networks get created by same name, and then compose fails to start container, throwing something like this - Cannot start Docker Compose application. Reason: compose [start] exit status 1. Container container-name Starting Error response from daemon: network network is ambiguous (4 matches found on name).

Above error happens if I try to run same compose command on 5 processes in parallel.

I still wonder if here is any way to do this though :sweat_smile:

Okay, so one partial workaround is available - passing a random value as a network name to the compose:

networks:
  default:
    name: ${NETWORK_NAME}

Each process would set this to a unique value, a single compose with one of the random names always gets successfully created, only issue is that networks of failed compose commands are left around as trash, which can be cleaned up by docker network prune.

To sum it up: you are hamming docker compose and try to create a single stack, which fails due to race conditions. Now you want to use different network names for the same stack to make sure you don’t suffer a race condition.

I am sure you are already aware of this: the docker cli, docker compose and docker-compose do not have control over the resources (container, networks, …). They just fire one of more calls to the docker engine, which then processes the calls asynchronous. This asynchronous behavior seem to trigger race conditions in your scenario.

The project name I was referring to is used to create independent stacks (all resources get prefix with {project name}_ ) that do not influence each other - they all become different deployments without any race conditions, even though they use the same compose file. But obviously this not what you want.

I have never seen someone come up with your container creating strategy in the last 9 years I work with containers. Usually pipelines are responsible to setup these kind of things and make sure that all bits and pieces are in place when they are needed.

I hope you will find what you are looking for!

The use case is also described in this accepted PR - networks: prevent issues due to duplicate names by milas · Pull Request #9585 · docker/compose · GitHub.

I understand that the problem is more with docker engine itself, so this post was not in the best forum, and whatever I am doing is an ugly workaround, but I also do not think that the described use case is that exotic these days.