Multiple docker-composes access single volume - docker

I have two separate docker-composes and I want them to have access to the same volume but I'm not sure the best approach for this.
This is a roughly how I am trying to make this work:
version: '3'
services:
container1:
volumes:
- myvolume
volumes:
myvolume:
version: '3'
services:
container2:
volumes:
- myvolume
I have one docker compose which defines ands uses a volume and I want to have the other docker compose to also have access to the volume.

I figured it out:
version: '3'
services:
container1:
volumes:
- internal-volume-name
volumes:
internal-volume-name:
name: external-volume-name
version: '3'
services:
container2:
volumes:
- internal-volume-name
volumes:
internal-volume-name:
external: true
name: external-volume-name
Where the volume is created, it must be given a name (external-volume-name).
When you want to reference it from another docker-compose, you must specify external: true and then specify the same given name (name: external-volume-name)

Related

How to config volumes in docker-compose.yml?

Is a very simple question I guess, but I could not find an answer.
This is my docker-compose.yml
version: '3'
services:
db:
volumes:
- db:/var/lib/mysql
volumes:
db:
nextcloud:
The question is, I want to specify the value of "db" or "nextcloud" in "volumes", and reference them in "Services".like this
services:
db:
volumes:
- db:/var/lib/mysql
nextcloud:
volumes:
- nextcloud:/var/www/html
volumes:
db: /home/roj/DataDisk/nextcloud-insecure/db
nextcloud: /home/roj/DataDisk/nextcloud-insecure/disk
but I got problemERROR: In file './docker-compose.yml', volume 'db' must be a mapping not a string.
how can i fix it ?
The top-level volumes section is not meant to specify mounts but volume driver configuration (see official documention on that matter). ie. this is incorrect
volumes:
db: /home/roj/DataDisk/nextcloud-insecure/db # incorrect
nextcloud: /home/roj/DataDisk/nextcloud-insecure/disk # incorrect
If you want to mount host directories to you container, you must specify it in the volumes section of your services, eg.
services:
db:
volumes:
- /home/roj/DataDisk/nextcloud-insecure/db:/var/lib/mysql
nextcloud:
volumes:
- /home/roj/DataDisk/nextcloud-insecure/disk:/var/www/html
See official documentation on services volumes for more information on that.
Your syntax in the outer volumes instruction is incorrect.
If you want to mount to a docker-managed volume, do this:
services:
test:
image: alpine
volumes:
- db:/app
volumes:
db:
If you want to mount to a local path, do this (you can replace the dot in .:/app with any other local path, like: /home/you:/server/path):
services:
test:
image: alpine
volumes:
- .:/app
If it starts with a dot or a slash, it will be treated as a path, otherwise, as a docker-managed named volume.
These are the common usage patterns, but you can read more about volumes in compose for some additional information.

Is it possible to set global settings for services in a docker compose file?

Is it possible to specify global settings for services in a Docker compose file?
For example, take this Docker Compose file:
version: "3.9"
services:
test1:
env_file: /path/to/env/file
image: test
container_name: test1
ports:
- "1234:22"
networks:
- dmz
restart: always
test2:
env_file: /path/to/env/file
image: test
container_name: test2
ports:
- "2345:22"
networks:
- trust
restart: always
networks:
dmz:
driver: bridge
trust:
driver: bridge
I don't want to have env_file: /path/to/env/file for every service and would like to make it apply to all services. I know I can pass it in the docker-compose command line but I'm hoping to do it from within the Docker compose file.
Although #timsmelik's answer points in the right direction and shows how to use a yaml anchor and alias with scalar values, you can probably take advantage of the merge key yaml feature here to set overridable default values for your services.
Here is an example to illustrate
version: "3.9"
x-service_defaults: &service_defaults
env_file: /path/to/env/file
image: test
restart: always
services:
test1:
<< : *service_defaults
container_name: test1
ports:
- "1234:22"
networks:
- dmz
test2:
<< : *service_defaults
container_name: test2
ports:
- "2345:22"
networks:
- trust
test3:
<< : *service_defaults
env_file: /some/override/env/file
container_name: test3
volumes:
- /some/bind/dir:/whatever/target
networks:
dmz:
driver: bridge
trust:
driver: bridge
You can find a pretty good comprehensive explanation of all possible yaml anchor/alias usage applied to docker-compose files in the following blog post
Try using extensions as fragments.
With the support for extension fields, Compose file can be written as follows to improve readability of reused fragments:
This is the example from the README.md:
x-logging: &default-logging
options:
max-size: "12m"
max-file: "5"
driver: json-file
services:
frontend:
image: awesome/webapp
logging: *default-logging
backend:
image: awesome/database
logging: *default-logging

How do I create an external volume using docker compose?

Basing on this Node-RED tutorial, I'm trying to mount an external volume with the Node-RED files outside the docker machine. I'm using the following docker-compose file:
version: "3.7"
services:
node-red:
image: nodered/node-red:latest
environment:
- TZ=Europe/Amsterdam
ports:
- "2000:1880"
networks:
- node-red-net
volumes:
- node-red-data:/home/user/node-red1
volumes:
node-red-data:
networks:
node-red-net:
However, even though this file works fine when I run docker-compose up, the volume exists only inside the docker machine. I've tried adding the line external: true in volumes but I get the following error:
ERROR: In file './docker-compose.yml', volume 'external' must be a mapping not a boolean.
What am I missing? How do I mount an external volume using docker-compose files?
I ended up finding a related question with this answer. There are multiple answers that didn't work for me there (also there's no accepted answer). The syntax that worked was:
node-red-data:
driver: local
driver_opts:
o: bind
type: none
device: /path/external/folder
So the final dockerfile that works after running docker-compose up is:
version: "3.7"
services:
node-red:
image: nodered/node-red:latest
environment:
- TZ=Europe/Amsterdam
ports:
- "2000:1880"
networks:
- node-red-net
volumes:
- node-red-data:/data
container_name: node-red
volumes:
node-red-data:
driver: local
driver_opts:
o: bind
type: none
device: "/home/user/node-red1"
networks:
node-red-net:
Update
If we don't mind having a random name for the volume, the following solution also works fine:
version: "3.7"
services:
node-red:
image: nodered/node-red:latest
environment:
- TZ=Europe/Amsterdam
ports:
- "2000:1880"
volumes:
- /home/user/node-red1:/data
container_name: node-red

docker volume mapped with filesystem (windows)

I have this lighted docker-compose file :
version: "2"
services:
orthanc:
build: orthanc
restart: unless-stopped
ports: ["${PORT}:8042"]
volumes: ["orthanc-storage:/var/lib/orthanc/db:Z"]
[...]
volumes:
orthanc-storage:
I don't understand how I finally define the volume orthanc-storage to link C:/tmp for example.
Someone could explain it to me ? thank you.
By default the driver used is local to assign volumes and creates the volume on host at /var/lib/docker/volumes/<project_name>_dbdata in Linux. Not confirm where does it points in windows.
You can define the volumes to use different driver and give the path to the volume like this
version: "2"
services:
orthanc:
build: orthanc
restart: unless-stopped
ports: ["${PORT}:8042"]
volumes: ["orthanc-storage:/var/lib/orthanc/db:Z"]
[...]
volumes:
orthanc-storage:
volumes:
orthanc-storage:
driver_opts:
type: 'none'
o: 'bind'
device: "C:/tmp"

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.

Resources