Import docker compose file in another compose file - docker

Is it possible to "import" or link a docker-compose file into another docker-compose file?
Suppose I have two files:
# docker-compose-1.yml
services:
A:
# config
B:
# config
# docker-compose-2.yml
services:
C:
# config
import: docker-compose-1.yml
By running docker-compose -f docker-compose-2.yml up, I would like to start containers A, B (specified in the imported file) and C. Is this possible, without having to link both files with the -f parameter?

By extending
It's possible to extend or use multiple docker-compose files and their services and link them in just one file. You can take a look at this link to understand how is the other usages of multiple compose files. But you can't include the file yet without linking related files together as you mentioned.
Here, I defined a common-services.yaml:
version: '2'
services:
nginx_a:
image: nginx:latest
container_name: nginx
ports:
- 81:80
- 1443:443
And then, I created a docker-compose.yml and included the common-services.yml file and its own service as well.
services:
nginx:
extends:
file: common-services.yml
service: nginx_a
nginx_b:
image: nginx:latest
container_name: nginx_b
volumes:
ports:
- 82:80
- 2443:443
By .env technique
And if you want to avoid chaining usage of multiple files, there is also a technique with .env files. I will rewrite the previous example with .env technique.
COMPOSE_PATH_SEPARATOR=:
COMPOSE_FILE=common-services.yml:docker-compose.yml
Let's add another service as an example in the common-services.yml
version: '2'
services:
ngin_a:
image: nginx:latest
container_name: nginx_a
ports:
- 81:80
- 1443:443
redis_c:
image: redis:latest
container_name: redis_c
ports:
- 6381:6380
And finally, load all of them in the docker-compose file without even mention to those services.
version: '2'
services:
nginx_b:
image: nginx:latest
container_name: nginx_b
ports:
- 82:80
- 2443:443
env_file:
- .env
In the end, you will have three running services.

Related

Why the services is not a list in docker-compose files

I am learning and testing docker with yaml. And I have created a simple docker-compose.yml file as:
version: "3"
services:
redis:
image: redis
click-counter:
image: kodekloud/click-counter
ports:
- 8080:5000
links:
- redis:redis
My question: Are the services under option services list(redis and click-counter). Then appending a dash should work but is not working.
version: "3"
services:
- redis:
image: redis
- click-counter:
image: kodekloud/click-counter
ports:
- 8080:5000
links:
- redis:redis
This throws errors in terminal as:
RROR: In file './docker-compose.yml', service must be a mapping, not an array.
Can any assist on the this.
services is a map in terms of Docker Compose YAML definition. It allows enforcing no duplicated services.
When you add - in front of the name of each service, services is going to be a list in terms of YAML definition. And therefore is not what is expected by Docker.
The first docker-compose file you have has the correct format for defining services.
version: "3"
services:
redis:
...
click-counter:
...

Docker compose Unsupported config option for service volume mongodb

I am trying to learn docker by reading the official documentation. I am on the task of Use Compose to develop locally. Trying to compose mongodb but I got an error
The Compose file './docker-compose.dev.yml' is invalid because:
Unsupported config option for services.volumes: 'mongodb'
here is docker-compose.dev.yml file:
version: '3.8'
services:
notes:
build:
context: .
ports:
- 8080:8080
- 9229:9229
environment:
- SERVER_PORT=8080
- DATABASE_CONNECTIONSTRING=mongodb://mongo:27017/notes
volumes:
- ./:/code
command: npm run debug
mongo:
image: mongo:4.2.8
ports:
- 27017:27017
volumes:
- mongodb:/data/db
- mongodb_config:/data/configdb
volumes:
mongodb:
mongodb_config:
How can I make it work?
That's a small mistake on your part, the volumes section of the docker-compose.yaml file is related to all services and not one in particular, because of how yaml files are formatted the indentation level matters a lot, in your example you didn't use the volumes parameter, instead you defined a service called volumes and services don't have a parameter called mongodb.
You have to simply decrease the identation level on the last 3 lines and it will work just fine.
version: '3.8'
services:
mongo:
image: mongo:4.2.8
ports:
- 27017:27017
volumes:
- mongodb:/data/db
- mongodb_config:/data/configdb
volumes:
mongodb:
mongodb_config:

How to exclude subfolders when using volume?

version: '3'
services:
nginx:
image: nginxtest
container_name: nginxtest-container
volumes:
- "$PWD:/apps"
ports:
- "80:80"
Above is my compose file.
I have created dummy file in that directory. If I want to ignore or exclude changes made in one file and all other files should be reflecting the change as it is, how to do that.
Let's say you want to mount $PWD but want to exclude $PWD/template, you can use this.
version: '3'
services:
nginx:
image: nginx
container_name: nginxtest-container
volumes:
- "/apps/template"
- "$PWD:/apps"
ports:
- "80:80"
/apps/template creates a separate space. Anything in $PWD/template will not be mirrored in the container, anything in /apps/template will also not be reflected on the host.

Docker-compose specify tags from env file

I have docker-compose.yml like below:
version: '2'
services:
micro-service:
image: some/micro-service:${SERVICE_VERSION}
env_file:
- ../all-variables/${PROFILE}/micro_service.env
ports:
- "8085:8085"
And I have two files : dev.env and stage.env where SERVICE_VERSION and PROFILE are described.
Is there any way to specify concrete file when running docker-compose up
By default docker-compose takes .env file from current dir.
Is there a way to override it or another workaround ?
As mentioned in the answer in the comments there is no way to do that as it is directly coded into the source code to use .env.
However, there a couple ways to get similar behaviour.
The first way works natively with docker-compose, which would be to use docker-compose override files.
So in your case you could have your base docker-compose.yml file like this:
version: '2'
services:
micro-service:
image: some/micro-service:1.0.0
ports:
- "8085:8085"
Then you can define a docker-compose-dev.yml file:
version: '2'
services:
micro-service:
image: some/micro-service:dev
env_file:
- ../all-variables/dev/micro_service.env
Then you can run the following command
$ docker-compose up -f docker-compose.yml -f docker-compose-dev.yml up
If you do this the values in docker-compose-dev.yml will override those in docker-compose.yml. So instead of using image some/micro-service:1.0.0 it will use the image defined in docker-compose-dev.yml.
The second way would be to use docker-app. Which is a new experimental utility from the Docker team.
Basically you will create a dockerapp file that would look like this:
version: 0.0.1
name: app
---
version: '2'
services:
micro-service:
image: some/micro-service:${SERVICE_VERSION}
env_file:
- ../all-variables/${PROFILE}/micro_service.env
ports:
- "8085:8085"
---
SERVICE_VERSION: latest
PROFILE: default
Then if you convert your .env files to .yml render the compose file with the correct variables using docker-app.
docker-app render -f dev.yml | docker-compose -f - up
Hopefully this is helpful, I am going through a similar issue when working with multiple environments with docker-compose.

How to share volumes among containers by docker-compose

My docker-compose defines two containers. I want one container shares a volume to the other container.
version: '3'
services:
web-server:
env_file: .env
container_name: web-server
image: web-server
build:
dockerfile: docker/Dockerfile
ports:
- 3000:3000
- 3500:3500
volumes:
- static-content: /workspace/static
command: sh /workspace/start.sh
backend-server:
volumes:
- static-content: /workspace/static
volumes:
static-content:
The above docker composer file declares two services, web-server and backend-server. And I declares the named volume static-content under services. I got below error when I run docker-composer -f docker-composer.yml up:
services.web-server.volumes contains an invalid type, it should be a string
services.backend-server.volumes contains an invalid type, it should be a string
so how can I share volumes throw docker-composer?
You have an extra space in your volume string that causes Yaml to change the parsing from an array of strings to an array of name/value maps. Remove that space in your volume entries (see below) to prevent this error:
version: '3'
services:
web-server:
env_file: .env
container_name: web-server
image: web-server
build:
dockerfile: docker/Dockerfile
ports:
- 3000:3000
- 3500:3500
volumes:
- static-content:/workspace/static
command: sh /workspace/start.sh
backend-server:
volumes:
- static-content:/workspace/static
volumes:
static-content:
For more details, see the compose file section on volumes short syntax.
You need to use the docker volumes syntax, without spaces
<local_path>:<service_path>:<optional_rw_attributes>
For example:
./:/your_path/
will map the present working directory to /your_path
And this example:
./:/your_path/:ro
will map the present working directory to /your_path with read only permissions
Read these docs for more info:
https://docs.docker.com/compose/compose-file/#volume-configuration-reference

Resources