Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to map volume paths using Docker's --volumes-from?

Tags:

docker

I'm new to Docker and am excited about using the --volumes-from feature but there's something I'm not understanding.

If I want to use --volumes-from with two data-only containers, each of which exports volumes named /srv, how to I prevent the volume paths from colliding? I can map volume names when creating a bind mount using [host-dir]:[container-dir]; how do I do that with --volumes-from?

So what I want would look something like this:

docker run --name=DATA1 --volume=/srv busybox true docker run --name=DATA2 --volume=/srv busybox true docker run -t -i -rm --volumes-from DATA1:/srv1 --volumes-from DATA2:/srv2 ubuntu bash 
like image 579
David Braun Avatar asked Apr 17 '14 15:04

David Braun


People also ask

How do I get a docker volume path?

Docker automatically creates a directory for the volume on the host under the /var/lib/docker/volume/ path. You can now mount this volume on a container, ensuring data persistence and data sharing among multiple containers.

How do I use Dockerfile volumes?

You can manage volumes using Docker CLI commands or the Docker API. Volumes work on both Linux and Windows containers. Volumes can be more safely shared among multiple containers. Volume drivers let you store volumes on remote hosts or cloud providers, to encrypt the contents of volumes, or to add other functionality.

Why would you choose data volume containers over data volumes?

The main advantage of both volumes and the data container pattern is that bind mounting on a host is host dependent, meaning you couldn't use that in a docker file. Volumes allow you the flexibility to define volumes when you build your images.


2 Answers

It can be done, but it is not supported at this moment in docker commandline interface.

How-to

Find the volumes directories:

docker inspect DATA1 | grep "vfs/dir" # output something like: # "/srv": "/var/lib/docker/vfs/dir/<long vol id>" 

So, you can automate this, and mount these directories at mount points of your choice:

# load directories in variables: SRV1=$(docker inspect DATA1 | grep "vfs/dir" | awk '/"(.*)"/ { gsub(/"/,"",$2); print $2 }') SRV2=$(docker inspect DATA2 | grep "vfs/dir" | awk '/"(.*)"/ { gsub(/"/,"",$2); print $2 }') 

now, mount these volumes by real directories instead of the --volumes-from:

docker run -t -i -v $SRV1:/srv1 -v $SRV2:/srv2 ubuntu bash 

IMO, the functionality is identical, because this is the same thing that is done when using --volumes-from.

like image 186
Jiri Avatar answered Sep 18 '22 19:09

Jiri


For completeness...

#create data containers docker run --name=d1 -v /svr1 busybox sh -c 'touch /svr1/some_data' docker run --name=d2 -v /svr2 busybox sh -c 'touch /svr2/some_data'  # all together... docker run --rm --volumes-from=d1 --volumes-from=d2 busybox sh -c 'find -name some_data' # prints: #  ./svr2/some_data #  ./svr1/some_data  # cleanup... docker rm -f d1 d2 

The "--volumes-from=container" just map over the filesystem, like mount --bind

If you want to change the path, Jiri's answer is (currently) the only way. But if you are in a limited environment you might want to use dockers built in inspect parsing capabilities:

# create data containers docker run --name=DATA1 --volume=/srv busybox sh -c 'touch /srv/some_data-1' docker run --name=DATA2 --volume=/srv busybox sh -c 'touch /srv/some_data-2'  # run with volumes and show the data docker run \   -v $(docker inspect -f '{{ index .Volumes "/srv" }}' DATA1):/srv1 \   -v $(docker inspect -f '{{ index .Volumes "/srv" }}' DATA2):/srv2 \   --rm busybox sh -c 'find -name some_data-*' # prints: # ./srv2/some_data-2 # ./srv1/some_data-1  # ditch data containers... docker rm -f DATA1 DATA2 

this probably even works with the old bash version that comes with boot2docker.

like image 42
Florian Fida Avatar answered Sep 18 '22 19:09

Florian Fida