malobre
malobre

Reputation: 69

Docker VOLUME instruction doesn't initialize the volume with existing data

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

Answers (2)

BMitch
BMitch

Reputation: 264236

There are several types of volumes:

  1. 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.

  2. 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.

  3. 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

tadman
tadman

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

Related Questions