45

My situation. Trying to run a docker-compose structure several times on the same box. This is my docker-compose.yml:

version: '3'
services:
  code:
    image: organization:java-maven
    links:
      - mysql:mysql
    volumes:
      - "${PWD}:/home/ubuntu/src"
  mysql:
    image: organization:mysql

Running this twice with docker-compose run code mvn clean test creates two containers of code and one container of mysql.

Now, I want one code to be linked to one mysql, and another code linked to another mysql.

How do I accomplish this? This is supposed to run on jenkins slaves and the maven executions cannot share mysql.

I've miserably failed trying with the "-e KEY=VALUE" option for docker-compose run together with container_namein the docker compose file.

Not sure how to approach this, please help, thank you.

Wrench
  • 4,070
  • 4
  • 34
  • 46
  • 1
    Why don't you specify second `code` container explicitly and link it with appropriate `mysql ` container, instead of running it "twice"? – antonbormotov Jan 24 '17 at 15:17
  • Because when jenkins triggers on a change in a branch, it starts an ec2 instance (build slave) and after that executes a jenkins pipeline. That pipeline runs the maven testing using the docker compose setup. Individual test executions in pipelines are not concerned of other running pipelines, and jenkins slaves are configured to run more than one executor. – Wrench Jan 24 '17 at 15:56
  • Is MySQL container should be same for all concurrent pipelines with code container? – antonbormotov Jan 24 '17 at 16:24
  • Nope, all pipeline containers should have their own MySQL container. – Wrench Jan 24 '17 at 16:53

1 Answers1

61

So, I focused too much on using directives to alter container names manually. The solution was much easier.

docker-compose -p anything run code mvn clean test

docker-compose -p anything_else run code mvn clean test

So, this is the project name solution. Docker compose will use the value given with the option -p as a prefix when creating container names. That means no collision.

Very handy!

For more reading: documentation around project-name option

Chris Maes
  • 35,025
  • 12
  • 111
  • 136
Wrench
  • 4,070
  • 4
  • 34
  • 46
  • 1
    +1 your question and answer. Another example would be for gradually introducing a new build into live. Load balancing between multiple containers, where 80% of them are running current build and 20% running new build and then 60% / 40% then 50% / 50% then 60 / 40% and so on, to see how the new build scales as it is gradually introduced. Of course, before this point, extensive testing would have been carried out: dev, unit, qa, uat and scaling. But one can never really know 100% until it is rolled out, so your answer can be applied for live roll out. – therobyouknow Jun 13 '18 at 20:19
  • 2
    this indeed fixed the problem, even if different docker-compose files reference the same image (the containers are recreated in that case). thanks for saving my day! – Stefan Dec 12 '18 at 12:33
  • 2
    Looks nice, though how would ports mapping be solved in this case? Say one service must be mapped with host port. So running this multiple time per project, you would need to specify port mapping during `docker-compose` call somehow (cause each new project/copy would need different host port to be mapped with)? – Andrius Nov 22 '20 at 12:44
  • @Andrius were you able to figure this out? I agree that this looks nice in theory, but not sure how ports and other services would map out like you mentioned. – theprogrammer Mar 25 '21 at 03:34
  • @theprogrammer You could create an override yml file for each of the environments to be started in which you override just the port mappings. This can be scripted of course in some shell script that is called in the Jenkins job. – JSamir Nov 18 '21 at 10:19
  • You can use environment variables for the port issue: ports: '${WEB_PORT:-4242}:8080' – Cola_Colin Jun 27 '23 at 13:48