How to specify volume host path in docker-compose? - docker

I want to share a volume among multiple containers, and specify the path for this volume on the host.
I used the following settings:
version: '3'
services:
service1:
image: image1
volumes:
- volume1:/volume1
service2:
image: image2
volumes:
- volume1:/volume1
volumes:
volume1:
driver: local # meaning?
driver_opts:
o: bind # meaning?
type: none # meaning?
device: /volume1 # the path on the host
But I am not sure of the driver: local, type: none and o: bind options.
I would like to have a regular volume (like without specifying any driver nor driver_opts), just being able to specify the path on the host.

You're looking for a bind mount. Specifying the volumes key means that you're creating a volume in the Docker machine for persistent storage. Despite the name, a volume is not necessarily related to volumes.
Use something like:
version: '3'
services:
service1:
image: image1
volumes:
- type: bind # Host and Docker machines have identical views to the same directory; changes propagate both ways
source: . # Host machine directory to mount
target: /app # Docker machine directory to be mapped to

Related

Mount OpenMediaVault NFS in docker-compose.yml volume for Docker Swarm

I am trying to externalise my runtime data from my applications to be saved in OpenMediaVault shared folder.
I was able to create shared folder and configure NFS or at least I think so. The config I see in OMV/Services/NFS/Shares is:
Shared folder: NasFolder[on /dev/sda1, nas/]
Client: 192.168.50.0/24
Privelage: Read/Write
Extra options: subtree_check,insecure
Now in that shared folder I have this structure(I checked it using windows SMB/CIFS config)
\\nfs-ip\NasFolder
|- mysql
| \- some my sql folders...
|- TEST.txt
I want to use this mysql folder to store MariaDB runtime data(I know names are messed up I am in a middle of a migration to Maria...). And meaby create some other folders for other services. This is my config from docker-compose.yml:
version: '3.2'
services:
mysqldb:
image: arm64v8/mariadb:latest
ports:
- 3306:3306
restart: on-failure:3
volumes:
- type: volume
source: nfs-volume
target: /mysql
volume:
nocopy: true
environment:
- MYSQL_ROOT_PASSWORD=my-secret-pw
command: --character-set-server=utf8 --collation-server=utf8_general_ci
volumes:
nfs-volume:
driver: local
driver_opts:
type: "nfs"
o: addr=192.168.50.70,nolock,soft,rw
device: ":/NasFolder"
Now when I run docker stack deploy -c docker-compose.yml --with-registry-auth maprealm on my manager node I get error on maprealm_mysqldb.1 that looks like this:
"Err": "starting container failed: error while mounting volume '/var/lib/docker/volumes/maprealm_nfs-volume/_data': failed to mount local volume: mount :/NasFolder:/var/lib/docker/volumes/maprealm_nfs-volume/_data, data: addr=192.168.50.70,nolock,soft: permission denied",
I am pretty new to integration stuff. This is my home server and I just can't find good tutorials that 'get through my thick skull' how to configure those NFS paths and permissions or at least how can I debug it beside just getting this error. I know that volumes.nfs-volume.driver_opts.device is supposed to be a path but I am not sure what path should that be.
I was trying to adapt config from here: https://gist.github.com/ruanbekker/4a9c0d250bce9f84482f2a788ce92131
Edit1) Few additional details:
Docker swarm has 3 nodes and only one node is manager with availability pause.
OMV is running on a separet machine that is not a part of a cluster
Ok so if someone would be looking for solution:
OMV by default has /export/ for NFS so volume needed to be updated. I needed to update volume for mysql and update volumes.mysql-volume.driver_opts.device to include that /export/ prefix and I also added path to mysql folder to have volume for mysqldb service use only:
volumes:
mysql-volume:
driver: local
driver_opts:
type: "nfs"
o: addr=192.168.50.70,nolock,soft,rw
device: ":/export/NasFolder/mysql"
After those changes there was need to update volume config on mysql/mariadb:
mysqldb:
image: arm64v8/mariadb:latest
ports:
- 3306:3306
restart: on-failure:3
volumes:
- type: volume
source: mysql-volume
target: /var/lib/mysql
volume:
nocopy: true
environment:
- MYSQL_ROOT_PASSWORD=my-secret-pw
command: --character-set-server=utf8 --collation-server=utf8_general_ci
mysqldb.volumes.source points to name of your volume defined in step 1 - mysql-volume
mysqldb.volumes.target is where inside container runtime data is stored. In mysql/mariadb databases runtime data is stored in /var/lib/mysql so you want to point to that and you can only use full path.
Since I used default OMV config there were problems with permissions. So I updated OMV/Services/NFS/Shares to this:
Shared folder: NasFolder[on /dev/sda1, nas/]
#here you can see note 'The location of the files to share. The share will be accessible at /export/.'
Client: 192.168.50.0/24
Privelage: Read/Write
Extra options: rw,sync,no_root_squash,anonuid=1000,anongid=1000,no_acl

How to find all unnamed modules

I got docker compose:
version: '2'
services:
elasticsearch:
image: 'elasticsearch:7.9.1'
environment:
- discovery.type=single-node
ports:
- '9200:9200'
- '9300:9300'
volumes:
- /var/lib/docker/volumes/elastic_search_volume:/usr/share/elasticsearch/data:rw
When I run:
docker volume ls
I see no results. How to list unnamed volumes?
docker volume ls as you've shown it will list all of the volumes that exist.
However, in the docker-compose.yml file you show, you're not creating a named or anonymous volume. Instead, you're creating a bind mount to connect a host directory to the container filesystem space. These aren't considered "volumes" in a technical Docker sense, and a docker volume command won't show or manipulate those.
Reaching directly into /var/lib/docker usually isn't a best practice. It's better to ask Docker Compose to manage the named volume for you:
version: '2'
services:
elasticsearch:
volumes:
# No absolute host path, just the volume name
- elastic_search_volume:/usr/share/elasticsearch/data:rw
volumes:
elastic_search_volume:
# Without this line, Compose will create the volume for you.
# With this line, Compose expects it to already exist; you may
# need to manually `docker volume create elastic_search_volume`.
# external: true

How to prevent a bind mounted directory to be overridden by container's data

My docker-compose.yml is like below where I have mounted my local dir code/drupal to /var/www/example.com. My container creates some temporary cache files inside /var/www/example.com/temp/. I want to map everything from container to host and host to container i.e in bidirectional but excluding the temp dir. Infact I don't want the content of that temp dir should be synchronized with my host machine.
version: "3.3"
services:
nginx:
build: ./docker/nginx
volumes:
- drupal:/var/www/example.com
volumes:
drupal:
driver: local
driver_opts:
type: none
device: $PWD/code/drupal
o: bind
Create a symlink from the problem directory to a non-volumed area in your docker container

Docker Named Volumes

What's the right way to mix named volumes with and without local host path in docker compose v3?
This way I'm getting YML error:
volumes:
/mnt/volume-part1:/volume
conf:
vhost:
html:
certs:
Then I'd like to refer to volume inside containers...
For named volumes, you need to declare the volume name under the dedicated volumes section in the compose file. For a mount, you don't declare it in that section:
Consider the following compose file:
version: "3"
services:
db:
image: db
volumes:
- data-volume:/var/lib/db
- /mnt/volume-part1:/volume
volumes:
data-volume:
As you can see the named volume data-volume needes to be declared in the volumes section before being assiged to the container.
Whereas the directory mount is directly mounted onto the container.
UPDATE
If you don't want to replicate the machine path on all the container, you can use a clever trick to specify where exactly the named volume will be created as such:
version: "3"
services:
db:
image: db
volumes:
- data-volume:/var/lib/db
- volume-part1:/volume
volumes:
data-volume:
volume-part1:
driver_opts:
type: none
device: /mnt/volume-part1
o: bind
As you can see above, we have created a named volume volume-part1 and specified where this volume will be backuped on the host machine.

How to set a path on host for a named volume in docker-compose.yml

Example below creates dbdata named volume and references it inside db service:
version: '2'
services:
db:
image: mysql
volumes:
- dbdata:/var/lib/mysql
volumes:
dbdata:
driver: local
(from https://stackoverflow.com/a/35675553/4291814)
I can see the path for the volume defaults to:
/var/lib/docker/volumes/<project_name>_dbdata
My question is how to configure the path on host for the dbdata volume?
With the local volume driver comes the ability to use arbitrary mounts; by using a bind mount you can achieve exactly this.
For setting up a named volume that gets mounted into /srv/db-data, your docker-compose.yml would look like this:
version: '2'
services:
db:
image: mysql
volumes:
- dbdata:/var/lib/mysql
volumes:
dbdata:
driver: local
driver_opts:
type: 'none'
o: 'bind'
device: '/srv/db-data'
I have not tested it with the version 2 of the compose file format, but https://docs.docker.com/compose/compose-file/compose-versioning/#version-2 does not indicate, that it should not work.
I've also not tested it on Windows...
The location of named volumes is managed by docker; if you want to specify the location yourself, you can either "bind mount" a host directory, or use a volume plugin that allows you to specify a path.
You can find some details in another answer I posted recently; https://stackoverflow.com/a/36321403/1811501

Resources