Reputation: 7789
I have been trying to read up on Docker volumes for a while now, but something still seems to be missing.
Take this Dockerfile
: (taken from docs)
FROM ubuntu
RUN mkdir /myvol
RUN echo "hello world" > /myvol/greeting
VOLUME /myvol
If I build and run this simply as docker run <img>
, then a new volume is created (its name can be found using docker inspect <containerid>
). The contents of /var/lib/docker/volumes/<volumeid>
is just a file greeting
containing hello world
, as expected.
So far so good. Now, say I wanted, as a user, to place this volume to a custom location. I would run docker run -v /host/path/:/myvol
. This does not work anymore. /host/path
is created (if it does not exist), but is empty.
So, the question is, how do I put some files in a Volume in Dockerfile, whilst allowing the user to choose where they put this volume? This seems to me to be one of the reasons to use Volume directive in the first place.
Upvotes: 3
Views: 3213
Reputation: 311740
So, the question is, how do I put some files in a Volume in Dockerfile, whilst allowing the user to choose where they put this volume?
You don't. A volume is created at runtime, while your Dockerfile is consulted at build time.
If you want to be able to pre-populate a volume at an arbitrary location when your container runs, allow the user to provide the path to the volume in an environment variable and then have an ENTRYPOINT script that copies the files into the volume when the container starts.
An alternative is to require the use of a specific path, and then taking advantage of the fact that if the user mounts a new, empty volume on that path, Docker will copy the contents of that directory into the volume. For example, if I have:
FROM alpine
RUN mkdir /data; echo "This is a test" > /data/datafile
VOLUME /data
And I build an image testimage
from that, and then run:
docker run -it testimage sh
I see that my volume in /data
contains the file(s) from the underlying filesystem:
/ # ls /data
datafile
This won't work if I mount a host path on that location, for example if I do:
host# mkdir /tmp/empty
host# docker run -it -v /tmp/empty:/data testimage sh
Then the resulting path will be empty:
/ # ls /data
/ #
This is another situation in which an ENTRYPOINT
script could be used to populate the target directory.
Upvotes: 4