FROM nginx:1.7
# Deliberately declaring VOLUME before RUN
VOLUME /var/tmp
RUN touch /var/tmp/test.txt
Observation
Now I believe I understand the implications of declaring the VOLUME statement before
creating test.txt - the volume /var/tmp exposed at runtime will be based on the intermediary container prior to the test.txt file is created so it will be empty (hope this observation is correct)
So as expected the following docker run does not show test.txt:
docker run kz/test-volume:0.1
But then I tried supplying the volume at runtime as below:
docker run -v /var/tmp kz/test-volume:0.1
Question
The outcome was the same. So what does this mean? does the -v /var/tmp in the docker run command map to the empty /var/tmp dir exposed by the VOLUME command in the Dockerfile and not the /var/tmp directory with the test.txt in the latest image?
As a general answer to your question: docker run options take precedence over anything in the Dockerfile; but some options (like -v/VOLUME) are additive, plus you’ve asked about a special case.
These two commands are identical; the first one gets an implicit -v /var/tmp option from the VOLUME statement in the Dockerfile.
Finally, there’s one more special case.
cat >Dockerfile <<EOF
FROM ubuntu:16.04
RUN mkdir /x && touch /x/y
VOLUME /x
CMD ls -l /x
EOF
docker build -t my/image .
docker run my/image
# shows /x/y
mkdir $PWD/y
docker run -v $PWD/y:/x/y my/xmage
# shows nothing
In the first case where Docker implicitly creates the volume, it is populated from the volume that was “baked in” to the image. In the second case where you provide an explicit host directory, there is no automatic population.