Вопрос

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
Это было полезно?

Решение

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.

Другие советы

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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top