docker-compose share local bind volume between multiple services - docker

I have a docker compose file for a mono repo.
I have multiple services that use the same code,
all the shared code is in the following folder structure:
* root
|-- * shared
- | -- * sharedA
| | -- src
| -
| -- * sharedB
- | -- src
-
When i run my services in development (from docker compose) I'm using a watch program that watches changes on shared/sharedA/src, shared/sharedB/src
my docker compose file looks something like this
version: '3'
services:
service_a:
build:
context: .
dockerfile: 'services/serviceA/Dockerfile'
volumes:
- ./services/serviceA/src/:/usr/src/app/services/serviceA/src
- ./shared/sharedA/src/:/usr/src/app/shared/sharedA/src
- ./shared/sharedB/src/:/usr/src/app/shared/sharedB/src
service_b:
build:
context: .
dockerfile: 'services/serviceB/Dockerfile'
volumes:
- ./services/serviceB/src/:/usr/src/app/services/serviceB/src
- ./shared/sharedA/src/:/usr/src/app/shared/sharedA/src
- ./shared/sharedB/src/:/usr/src/app/shared/sharedB/src
My goal is to have the volumes declaration of
- ./shared/sharedA/src/:/usr/src/app/shared/sharedA/src
- ./shared/sharedB/src/:/usr/src/app/shared/sharedB/src
in a central place that will allow me to define them once and import/connect them in each service,
tried going through this guide + docker compose docs http://blog.code4hire.com/2018/06/define-named-volume-with-host-mount-in-the-docker-compose-file/ with some alterations to achieve it, but unfortunately i couldn't get it working..
I'm not sure it's even possible but the documentation about docker compose volumes isn't really helpful so i thought maybe someone here already dealt with something similar 🙂

You can use named volumes:
version: '3'
services:
service_a:
build:
context: .
dockerfile: 'services/serviceA/Dockerfile'
volumes:
- sharedA:/usr/src/app/shared/sharedA/src
- sharedB:/usr/src/app/shared/sharedB/src
service_b:
build:
context: .
dockerfile: 'services/serviceB/Dockerfile'
volumes:
- sharedA:/usr/src/app/shared/sharedA/src
- sharedB:/usr/src/app/shared/sharedB/src
volumes:
sharedA:
driver: local
driver_opts:
type: none
device: ./shared/sharedA/src/
o: bind
sharedB:
driver: local
driver_opts:
type: none
device: ./shared/sharedB/src/
o: bind

Related

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-compose : absolute path for shared volumes in version 3

To replace the volumes_from: directive from version 2 (for helpyio), I tried this, but something went wrong.
version: "3"
services:
frontend:
...
volumes:
- myVolume:/var/www:ro
backend:
...
volumes:
- myVolume:/var/www
volumes:
myVolume:
driver: local
driver_opts:
type: none
device: "/my/local/absolute/path/"
o: bind
I have errors like
ERROR: for frontend: Cannot create container for service frontend: failed to mount local volume: mount /my/local/absolute/path/:/var/www, flags: 0x1000: no such file or directory
I also tried some variant in volumes: options but without success. And last thing, I don't want to create manually this local directory.
I am sure to miss something, but can't see what... Has anyone a solution for this use case?
Many thanks
There's no reason to make your docker-compose.yml that complicated. You can simply do this:
version: "3"
services:
frontend:
...
volumes:
- /my/local/absolute/path/:/var/www:ro
backend:
...
volumes:
- /my/local/absolute/path/:/var/www
make custom directory:
sudo mkdir /static
and edit file
docker-compose.yml
version: "3.9"
services:
web:
volumes:
- "static_volume:/app/media"
volumes:
static_volume:
driver: local
driver_opts:
type: volume
o: bind
device: /static

Docker Windows Containers and NFS Volume

I have successfully created a Windows Docker Image and I can successfully run the container with docker-compose, for full functionality the application expects a folder location to exist, which is currently a NFS attached drive that contains a folder inside it that the application reads and writes to and is also used by other applications.
I have tried to find valid examples and documentation on Docker for Windows, Windows Containers and Docker Compose for Volumes that are NFS.
This is what I am currently trying
version: "3.4"
services:
service:
build:
context: .
dockerfile: ./Dockerfile
image: imageName
ports:
- 8085:80
environment:
-
volumes:
- type: volume
source: nfs_example
target: C:\example
volume:
nocopy: true
volumes:
nfs_example:
driver: local
driver_opts:
type: "nfs"
o: "addr=\\fileserver.domain,nolock,soft,rw"
device: ":\\Shared\\Folder"
The error message I get is:
ERROR: create service_nfs_example: options are not supported on this platform
NFS doesn't work.I solved it using SMB on the host, then mounted that volume.
New-SmbGlobalMapping -RemotePath \\contosofileserver\share1 -Credential Get-Credentials -LocalPath G:
version: "3.4"
services:
service:
build:
context: .
dockerfile: ./Dockerfile
image: imageName
ports:
- 8085:80
environment:
-
volumes:
- type: bind
source: G:\share1
target: C:\inside\container
This microsoft documentation on the windows containers helped me achieve this.

Docker compose-Mount volume on a few containers AND the host

Im trying to share data between a few containers and the host using docker-compose. I have a docker-compose.yml file that looks like this:
version: '3'
services:
base:
container_name: base
build:
context: .
dockerfile: BaseDockerfile
volumes:
- dependencies:/volumes/dependencies
romee:
container_name: romee
build:
context: .
dockerfile: RomeeDockerfile
environment:
- PYTHONPATH=/volumes/base_dependencies/
volumes:
- dependencies:/volumes/base_dependencies
volumes:
dependencies:
Now the volume "dependencies" is shared successfully between the containers, but I want to also share it with the host. How can I do that?
The question is equivalent to how to specify a path of a named volume:
Solution:
volumes:
dependencies:
driver: local
driver_opts:
type: 'none'
o: 'bind'
device: '/abs/path/to/dependencies'
EDIT
The complete flow would be like,
Image: Dependency generator, at build time (docker build), generate dependency to /temp, then at run time (docker run / docker-compose up), cp -pr /temp /dependencies, after that it can exit 0.

docker-compose volumes_from equivalent with version 3

I'm trying to create an Nginx/PHP FPM setup with docker compose and am having issues with the version 3 volumes syntax/changes.
My Dockerfile:
FROM php:7-fpm
VOLUME /var/www/html
My docker-compose.yml:
version: "3"
services:
php:
build: .
volumes:
- ./html:/var/www/html
web:
image: nginx
links:
- php
ports:
- "8888:80"
volumes:
- php:/var/www/html
- ./default.conf:/etc/nginx/conf.d/default.conf
volumes:
php:
When I add an index.php file into ./html, I can view that by going to http://localhost:8888, but any static files (like CSS) return a 404 because Nginx cannot find those in its container (/var/www/html is empty on the nginx container). With version 3 docker compose files do not have volumes_from anymore, which is basically what I'm trying to replicate.
How can I get this to work with version 3?
For using "Named volumes" for sharing files between containers you need to define
1) volumes: section on the top level of yml file and define volume name
volumes:
php:
2) define volume section on first container like you did (Where share will mount)
web:
volumes:
- php:/var/www/html #<container_name>:<mount_point>
3) define volume section on second container (Share will mount from)
php:
volumes:
- php:/var/www/html
4) (optionally) If you need to store volume data on the host machine you can use local-persist docker plugin. You can specify docker volume driver and path where you data will be stored.
volumes:
php:
driver: local-persist
driver_opts:
mountpoint: /path/on/host/machine/
In your case you forgot define volume name for php container. Just replace
php:
build: .
volumes:
- ./html:/var/www/html
to
php:
build: .
volumes:
- php:/var/www/html
and use Local Persist Docker Plugin

Resources