I have successfully been able to share folders between a docker container with volumes using
docker run -v /host/path:/container/path ...
B
The VOLUME
command will mount a directory inside your container and store any files created or edited inside that directory on your hosts disk outside the container file structure, bypassing the union file system.
The idea is that your volumes can be shared between your docker containers and they will stay around as long as there's a container (running or stopped) that references them.
You can have other containers mount existing volumes (effectively sharing them between containers) by using the --volumes-from
command when you run a container.
The fundamental difference between VOLUME
and -v
is this: -v
will mount existing files from your operating system inside your docker container and VOLUME
will create a new, empty volume on your host and mount it inside your container.
Example:
VOLUME /var/lib/mysql
.some-volume
And then,
docker run --volumes-from some-volume docker-image-name:tag
some-volume
mounted in /var/lib/mysql
Note: Using --volumes-from
will mount the volume over whatever exists in the location of the volume. I.e., if you had stuff in /var/lib/mysql
, it will be replaced with the contents of the volume.
VOLUME is used in Dockerfile
to expose the volume to be used by other containers. Example, create Dockerfile
as:
FROM ubuntu:14.04
RUN mkdir /myvol
RUN echo "hello world" > /myvol/greeting
VOLUME /myvol
build the image:
$ docker build -t testing_volume .
Run the container, say container1:
$ docker run -it <image-id of above image> bash
Now run another container with volumes-from option as (say-container2)
$ docker run -it --volumes-from <id-of-above-container> ubuntu:14.04 bash
You will get all data from container1 /myvol
directory into container2 at same location.
-v
option is given at run time of container which is used to mount container's directory on host. It is simple to use, just provide -v
option with argument as <host-path>:<container-path>
. The whole command may be as $ docker run -v <host-path>:<container-path> <image-id>
Let me add my own answer, because I believe the others are missing the point of Docker.
Using VOLUME
in the Dockerfile is the Right Way™, because you let Docker know that a certain directory contains permanent data. Docker will create a volume for that data and never delete it, even if you remove all the containers that use it.
It also bypasses the union file system, so that the volume is in fact an actual directory that gets mounted (read-write or readonly) in the right place in all the containers that share it.
Now, in order to access that data from the host, you only need to inspect your container:
# docker inspect myapp
[{
.
.
.
"Volumes": {
"/var/www": "/var/lib/docker/vfs/dir/b3ef4bc28fb39034dd7a3aab00e086e6...",
"/var/cache/nginx": "/var/lib/docker/vfs/dir/62499e6b31cb3f7f59bf00d8a16b48d2...",
"/var/log/nginx": "/var/lib/docker/vfs/dir/71896ce364ef919592f4e99c6e22ce87..."
},
"VolumesRW": {
"/var/www": false,
"/var/cache/nginx": true,
"/var/log/nginx": true
}
}]
What I usually do is make symlinks in some standard place such as /srv, so that I can easily access the volumes and manage the data they contain (only for the volumes you care about):
ln -s /var/lib/docker/vfs/dir/b3ef4bc28fb39034dd7a3aab00e086e6... /srv/myapp-www
ln -s /var/lib/docker/vfs/dir/71896ce364ef919592f4e99c6e22ce87... /srv/myapp-log
This is from the Docker documentation itself, might be of help, simple and plain:
"The host directory is, by its nature, host-dependent. For this reason, you can’t mount a host directory from Dockerfile, the VOLUME instruction does not support passing a host-dir, because built images should be portable. A host directory wouldn’t be available on all potential hosts.".
Basically VOLUME
and -v
option are almost equal. These mean 'mount specific directory on your container'. For example, VOLUME /data
and -v /data
is exactly same meaning. If you run the image that have VOLUME /data
or with -v /data
option, /data
directory is mounted your container. This directory doesn't belong to your container.
Imagine that You add some files to /data
on the container, then commit the container into new image. There isn't any files on data directory because mounted /data
directory is belong to original container.
$ docker run -it -v /data --name volume ubuntu:14.04 bash
root@2b5e0f2d37cd:/# cd /data
root@2b5e0f2d37cd:/data# touch 1 2 3 4 5 6 7 8 9
root@2b5e0f2d37cd:/data# cd /tmp
root@2b5e0f2d37cd:/tmp# touch 1 2 3 4 5 6 7 8 9
root@2b5e0f2d37cd:/tmp# exit
exit
$ docker commit volume nacyot/volume
835cfe3d8d159622507ba3256bb1c0b0d6e7c1419ae32751ad0f925c40378945
nacyot $ docker run -it nacyot/volume
root@dbe335c7e64d:/# cd /data
root@dbe335c7e64d:/data# ls
root@dbe335c7e64d:/data# cd /tmp
root@dbe335c7e64d:/tmp# ls
1 2 3 4 5 6 7 8 9
root@dbe335c7e64d:/tmp#
root@dbe335c7e64d:/tmp#
This mounted directory like /data
is used to store data that is not belong to your application. And you can predefine the data directory that is not belong to the container by using VOLUME
.
A difference between Volume
and -v
option is that you can use -v
option dynamically on starting container. It mean you can mount some directory dynamically. And another difference is that you can mount your host directory on your container by using -v
If you came here because you were looking for a simple way to browse any VOLUME
:
docker volume list
docker run -it --rm --mount source=[NAME OF VOLUME],target=/volume busybox
cd /volume
to enter the volume.