docker-compose collapse after running another instance of docker-compose [duplicate] - docker

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.

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

Related

Is there a recommended way to test Docker compose file (ideally, deployed as stacks)?

In the philosphy that every piece of software should be tested, is there a way to test a Docker compose file?
We are already aware of the Docker recommended way to test individual containers' Dockerfiles, with a sut service:
https://docs.docker.com/docker-hub/builds/automated-testing/
Yet, it is common to then assemble several containers as services of a docker-compose.yml file. Yet, we are not aware of any "recommended" (by the official doc, nor the community) approach to implement such test.
Naïvely, we could write some docker-compose.stacktest.yml along the line of:
version: '3.5'
services:
stacktest:
image: my-test-image
command: test.sh
Then run it something like:
docker stack deploy -c docker-compose.yml -c docker-compose.stacktest.yml tester
Yet we are interested to see if there is something more generally accepted out there?
One of the approaches I would follow is to use testcontainers-java
https://github.com/testcontainers/testcontainers-java
It has a feature where it runs a docker-compose file
https://www.testcontainers.org/modules/docker_compose/
The idea can be to write a bunch of tests in Java that runs the docker-compose and write assertions on them.
I never tried testcontainers-java for this purpose but I think it will work

How to append command to docker-compose.yml without override existing?

In docker-compose.yml I have a service
app:
image: yiisoftware/yii2-php:7.1-apache
volumes:
- ~/.composer-docker/cache:/root/.composer/cache:delegated
- ./:/app:delegated
ports:
- '80:80'
depends_on:
- db
So I want to execute command yii migrate --interactive=0 when container is started. But if I just add string
command: "yii migrate --interactive=0"
It override command that already specified in yiisoftware/yii2-php:7.1-apache dockerfile. How can I append command, not replace? Is it possible?
I already googled for this problem, but most popular solution is "create your own dockerfile". Can I solve this without create/modify dockerfile or shell script, only with docker-compose?
To do this, you would have to define your own ENTRYPOINT in your docker-compose.yml. Besides building your own Dockerfile, there is no way around this.
As much as I am searching, I cannot find a CMD instruction in this image's Dockerfile, though. So this is probably what's being used.
I'm not familiar with PHP, so I cannot estimate what you would have to change to run a container with your specific needs, but these are the points that you should have a look at.
You can include the pre-existing command in your new command. Now understand that everything in those commands can be called from sh or bash. So look up the existing command by doing an:
docker image inspect yiisoftware/yii2-php:7.1-apache
Then check the command in Config { Command }. (Not ConatinerConfig.) So if the existing command had been:
"start-daemon -z foo-bar"
then your new command would be:
sh -c "start-daemon -z foo-bar; yii migrate --interactive=0"
Now you'll have the existing command plus your new command and the desired effect.

How do I keep a copy of the options I use to run an image in Docker?

I just figured out how to get swagger-ui up and running with Docker with my own openapi.json file using the following command:
docker run -p 80:8080 -e SWAGGER_JSON=/foo/openapi.json -v ~/source:/foo swaggerapi/swagger-ui
The openapi.json file is in source control and this could be run in lots of places.
Is there any way to make this command easy to rerun other than just putting it in a README? Can I use a Dockerfile for this? Or could I use docker-compose? The most important part is just to make it easy, and then later to make it easy to change/add options.
I also know I could use a bash script that I could just change, but I'm wondering if there's any Docker way to do it, and not a hack.
docker-compose is your perfect solution:
//docker-compose.yml
version: '3.7'
services:
swagger:
image: swaggerapi/swagger-ui
ports:
- "80:8080"
environment:
- SWAGGER_JSON=/foo/openapi.json
volumes:
- "~/source:/foo "
to run it, just hit docker-compose up and you are all set
I prefer using docker-compose for more complicated runs to keep all options in yaml file. Then all you need to start container is docker-compose up.
For more options inside application you can use .env file.
I think it’s the clearest way to make containers running and doesn’t require any knowledge for the next users/developers of this environment .

Set $PROJECT_NAME in docker-compose file

I am using the same docker-compose.yml file for multiple projects. I am really lazy, so I don't want to start them with docker-compose -p $PROJECT_NAME up.
As of Docker version 17.06.0, is it possible to set the variable directly in the docker-compose.yml file?
UPDATE: You can now use the top-level name property in your docker-compose YAML file. This is available from Docker Compose v2.3.3
This is the result of the #745 proposal. An issue which persevered for about 8 years.
Previously:
Right now, we can use the .env file to set the custom project name like this:
COMPOSE_PROJECT_NAME=SOMEPROJECTNAME
It's not flexible, but it's better than nothing. Currently, there is an open issue regarding this as a proposal.
I know this question was asked a long time ago, but I ran into the same problem. There's a suggestion to add the feature https://github.com/docker/compose/issues/745, but they don't want to.
However, I have a Makefile in the root of the directory and then you can add something like in the Makefile:
.PHONY: container-name
container-name:
docker-compose -p $PROJECT_NAME up -d container-name
and then run make container-name
I know it isn't what you asked for, but could maybe make your life a bit easier.
220806 UPDATE: you can now use the top-level name property in your docker-compose YAML file.
This is the result of the #745 proposal.
Update as on Docker Compose version 2.3.3, name can be given in the compose file, but please note the following as per documentation compose-spec at github.com., Compose official documentation
Whenever project name is defined by top-level name or by some custom mechanism, it MUST be exposed for interpolation and environment variable resolution as COMPOSE_PROJECT_NAME.
name: stitch
services:
foo:
image: busybox
environment:
- COMPOSE_PROJECT_NAME
command: echo "I'm running ${COMPOSE_PROJECT_NAME}"
Previously proposed solution :
You can add them as your environment variables which are available through the session in which you are bringing up your containers using the docker compose.
Ie, if you wanted to use $PROJECT_NAME somewhere inside your docker-compose.yaml then if this variable has a value in your session, then it would be picked up.
Inside the yaml you can assign it to anything as you want it. You want as a commandline arg to some script, even that is also possible. ie,
working_dir: /opt
command: /bin/bash -c './script.sh ${PROJECT_NAME}'
volumes:
- /var/run/:/host/var/run/
I'm using
docker version : Docker version 17.09.0-ce, build afdb6d4
docker-compose version : docker-compose version 1.14.0, build c7bdf9e

How do I run the same docker-compose.yml several times on same docker daemon with different names?

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.
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

Resources