Reputation: 69
According to the Docker documentation regarding the VOLUME
instruction:
The
docker run
command initializes the newly created volume with any data that exists at the specified location within the base image. For example, consider the following Dockerfile snippet:FROM ubuntu RUN mkdir /myvol RUN echo "hello world" > /myvol/greeting VOLUME /myvol
This Dockerfile results in an image that causes docker run to create a new mount point at /myvol and copy the greeting file into the newly created volume.
I am unable to replicate this behaviour using this exact Dockerfile and running:
$ docker run --volume ~/testdir:/myvol 159b3387c7eb
The testdir
directory is created by does not contain the expected greeting
file.
What am I doing wrong ?
Upvotes: 1
Views: 2000
Reputation: 264236
There are several types of volumes:
Host volume, which bind mounts a directory from the host into a container. Docker never initializes these. Whatever the state of the host becomes the directory contents in that directory. This is the type of volume you created. They have the downside of having uid/gid permission issues when the container uid/gid does not match that of your host user.
Anonymous volume, which is a named volume with a long guid for a name. There is no information of what the target of an anonymous volume was, especially when the container has been deleted, so you'll want to give your volumes a name at least. These are the default if you define a volume with VOLUME
and then forget to define a volume when running the container.
Named volume, which is created by giving it a valid name rather than a path as a source. These are recommended for most scenarios, unless you need external access to your data with a host volume. The advantage of named volumes is that docker initializes them upon creation to the contents of your image at that location. This initialization only happens when the volume is first created, so changes to the image will not be reflected unless you have something like an entrypoint to copy data from another directory back out to your volume.
If you want to see a named volume with the data initialized, that would look like:
$ docker run --volume testvol:/myvol 159b3387c7eb
to create a volume called testvol
.
Upvotes: 4
Reputation: 211670
When you declare a VOLUME
that doesn't pre-populate the volume with anything, it just describes an intended mount-point.
When you call Docker with the --volume
argument it replaces anything in that target directory with your local directory, effectively mounting that local directory on top of the target location. Anything in that original location is obscured by the mount and inaccessible.
If you need to pre-populate the volume with content either do it before you mount it, or have an ENTRYPOINT
script that initializes that directory when the container boots up.
Upvotes: 0