What is the purpose of VOLUME in Dockerfile

A volume is a persistent data stored in /var/lib/docker/volumes/...

  • You can either declare it in a Dockerfile, which means each time a container is started from the image, the volume is created (empty), even if you don't have any -v option.

  • You can declare it on runtime docker run -v [host-dir:]container-dir.
    combining the two (VOLUME + docker run -v) means that you can mount the content of a host folder into your volume persisted by the container in /var/lib/docker/volumes/...

  • docker volume create creates a volume without having to define a Dockerfile and build an image and run a container. It is used to quickly allow other containers to mount said volume.

If you had persisted some content in a volume, but since then deleted the container (which by default does not deleted its associated volume, unless you are using docker rm -v), you can re-attach said volume to a new container (declaring the same volume).

See "Docker - How to access a volume not attached to a container?".
With docker volume create, this is easy to reattached a named volume to a container.

docker volume create --name aname
docker run -v aname:/apath --name acontainer
...
# modify data in /apath
...
docker rm acontainer

# let's mount aname volume again
docker run -v aname:/apath --name acontainer
ls /apath
# you find your data back!

VOLUME instruction becomes interesting when you combine it with volumes-from runtime parameter.

Given the following Dockerfile:

FROM busybox
VOLUME /myvolume

Build an image with:

docker build -t my-busybox .

And spin up a container with:

docker run --rm -it --name my-busybox-1 my-busybox

The first thing to notice is you will have a folder in this image named myvolume. But it is not particularly interesting since when we exit the container the volume will be removed as well.

Create an empty file in this folder, so run the following in the container:

cd myvolume
touch hello.txt

Now spin up a new container, but share the same volume with my-busybox-1:

docker run --rm -it --volumes-from my-busybox-1 --name my-busybox-2 my-busybox

You will see that my-busybox-2 contains the file hello.txt in myvolume folder.

Once you exit both containers, the volume will be removed as well.


@radium226

  1. Specifying VOLUME in Dockerfile makes sure the folder is to be treated as a volume(i.e., outside container) at runtime, as opposed to be a regular directory inside the container. Note the performance and accessibility implications.
  2. If having forgot to specify "-v" in "docker run" command line, the above is still true. It's just the volume name becomes anonymous. But there are still ways to access or recover data from such anonymous volumes.