Answers: <p><strong>Short version</strong>  </p>
  
  <p><code>VOLUME</code> instruction and <code>-v dest</code> are used to create unnamed/anonymous volumes, <code>-v scr:dest</code> option is for mapped volume.</p>
  
  <p><strong>Long Version</strong></p>
  
  <p>Dockerfile's <code>VOLUME</code> does not allow you to specify a host path.<br>
  On the host-side, the volumes are created with a very long ID-like name, these volumes are often referred to as unnamed/anonymous volumes.</p>
  
  <p>Given this Dockerfile:</p>
  
  <pre><code>FROM php7:latest
  VOLUME /var/www
  </code></pre>
  
  <p>Build it:</p>
  
  <pre><code>docker build -t myTest
  </code></pre>
  
  <p>Run it :</p>
  
  <pre><code>docker run --rm -it myTest
  </code></pre>
  
  <p>Inside the container, run <code>ls</code> and you'll notice the directory exists; <code>/var/www</code> </p>
  
  <p>Running the container also creates a directory on the host-side.</p>
  
  <p>While having the container running, execute <code>docker volume ls</code> on the host machine and you'll see something like this </p>
  
  <pre><code>DRIVER    VOLUME NAME
  local     c984..e4fc
  </code></pre>
  
  <p>Back in the <em>container</em>, execute <code>touch /var/www/myFile</code></p>
  
  <p>This file is now available on the host machine, in one of the unnamed volumes. </p>
  
  <pre><code>ls /var/lib/docker/volumes/c984..e4fc/_data
  </code></pre>
  
  <p>Similarly, you can try to delete this file on the host and it will be deleted in the container as well.</p>
  
  <p>Now run a new container, but specify a volume using <code>-v</code>:</p>
  
  <pre><code>docker run --rm -it -v /myVolume myTest
  </code></pre>
  
  <p>This <em>adds</em> a second volume and the whole system ends up having two unnamed volumes.
  On the host-side, the new second volume is anonymous and resides together with the other volume in <code>/var/lib/docker/volumes/</code>.</p>
  
  <p>It was stated earlier that the <code>Dockerfile</code> can not map to a host path which sort of pose a problem for us when trying to bring files in from the host to the container during runtime. A different <code>-v</code> syntax solves this problem.</p>
  
  <p>Imagine I have a subfolder in my project directory <code>./src</code> that I wish to sync to <code>/src</code> inside the container. This command does the trick:</p>
  
  <pre><code>docker run -it -v $(pwd)/src:/src myTest
  </code></pre>
  
  <p>Both sides of the <code>:</code> character expects an absolute path. Left side being an absolute path on the host machine, right side being an absolute path inside the container.</p>
  
  <p>We run this command:</p>
  
  <pre><code>docker run -v $(pwd)/src:/src myTest
  </code></pre>
  
  <p><strong>Is the specification purely informational?</strong></p>
  
  <p>No, it does mount a volume, it's similar to <code>-v /var/www</code> you just don't specify a mount point in the host machine, so docker will take care of it.</p>
  
  <p><strong>What are the (dis)advantages of (not) specifying volumes?</strong><br>
  <strong>Why and in which cases should I use VOLUME and when shouldn't I?</strong></p>
  
  <p>It's probably a best practice to never use <code>VOLUME</code>.<br>
  The first reason we have already identified: We can not specify the host path.<br>
  The second reason is people might forget to use the <code>--rm</code> option when running the container, you will end up with a couple of unused volumes and it might be a daunting task to figure out which of all anonymous volumes are safe to remove </p>
  
  <p><strong>What about files that may optionally be mounted? Do they count as volumes in that case, too?</strong></p>
  
  <p>In this case you don't need volumes; mapping a single file does not make sense, I would use <code>ADD</code> or <code>COPY</code> inside the dockerfile.</p>
  
Answers: CC BY-SA 4.0
Answers: 2018-10-02T13:00:24.103Z
Answers: 2018-10-02T14:25:31.027Z
Answers: 2018-10-02T14:25:31.027Z
Answers: storm
Body: <p>When writing a Dockerfile, I do have the option of specifying volumes, such as:</p>
  
  <pre><code>VOLUME /var/www
  </code></pre>
  
  <p>But even without this declaration I am able to mount volumes to this directory and other places, e.g. by using <code>-v /foo:/var/www</code> or -v <code>./httpd/conf.d:/usr/local/apache2/conf/conf.d</code> for bind mounts when running docker.</p>
  
  <p>So:</p>
  
  <ol>
  <li>Is the specification purely informational?</li>
  <li>What are the (dis)advantages of (not) specifying volumes?</li>
  <li>Why and in which cases should I use <code>VOLUME</code> and when shouldn't I?</li>
  <li>What about files that may optionally be mounted? Do they count as volumes in that case, too?</li>
  </ol>
  
Comments: CC BY-SA 4.0
Comments: 2018-10-02T13:33:06.593Z
Comments: VOLUME in the dockerfile existed before named volumes, in a time when the only way for persistent data was to use data containers where you would mount volumes from one container into another. This has been deprecated and my advice is to avoid them in a Dockerfile.
Comments: BMitch
Tags: <docker><dockerfile>
Title: When exactly and what for should VOLUME in a Dockerfile be used?
UserDisplayName: Thomas Luzat
ThreadText: # When exactly and what for should VOLUME in a Dockerfile be used?
  
  (Asked by: username_0 on 2018-10-01)
  
  When writing a Dockerfile, I do have the option of specifying volumes, such as:
  
  ```
  VOLUME /var/www
  
  ```
  
  But even without this declaration I am able to mount volumes to this directory and other places, e.g. by using `-v /foo:/var/www` or -v `./httpd/conf.d:/usr/local/apache2/conf/conf.d` for bind mounts when running docker.
  
  So:
  
  1. Is the specification purely informational?
  2. What are the (dis)advantages of (not) specifying volumes?
  3. Why and in which cases should I use `VOLUME` and when shouldn't I?
  4. What about files that may optionally be mounted? Do they count as volumes in that case, too?
  
  **Tags:** docker, dockerfile
  
  > **Comments:**
  > **username_1**: VOLUME in the dockerfile existed before named volumes, in a time when the only way for persistent data was to use data containers where you would mount volumes from one container into another. This has been deprecated and my advice is to avoid them in a Dockerfile.  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_2 on 2018-10-02. Score: 3
  
  **Short version**
  
  `VOLUME` instruction and `-v dest` are used to create unnamed/anonymous volumes, `-v scr:dest` option is for mapped volume.
  
  **Long Version**
  
  Dockerfile's `VOLUME` does not allow you to specify a host path.  
  On the host-side, the volumes are created with a very long ID-like name, these volumes are often referred to as unnamed/anonymous volumes.
  
  Given this Dockerfile:
  
  ```
  FROM php7:latest
  VOLUME /var/www
  
  ```
  
  Build it:
  
  ```
  docker build -t myTest
  
  ```
  
  Run it :
  
  ```
  docker run --rm -it myTest
  
  ```
  
  Inside the container, run `ls` and you'll notice the directory exists; `/var/www`
  
  Running the container also creates a directory on the host-side.
  
  While having the container running, execute `docker volume ls` on the host machine and you'll see something like this
  
  ```
  DRIVER    VOLUME NAME
  local     c984..e4fc
  
  ```
  
  Back in the *container*, execute `touch /var/www/myFile`
  
  This file is now available on the host machine, in one of the unnamed volumes.
  
  ```
  ls /var/lib/docker/volumes/c984..e4fc/_data
  
  ```
  
  Similarly, you can try to delete this file on the host and it will be deleted in the container as well.
  
  Now run a new container, but specify a volume using `-v`:
  
  ```
  docker run --rm -it -v /myVolume myTest
  
  ```
  
  This *adds* a second volume and the whole system ends up having two unnamed volumes.
  On the host-side, the new second volume is anonymous and resides together with the other volume in `/var/lib/docker/volumes/`.
  
  It was stated earlier that the `Dockerfile` can not map to a host path which sort of pose a problem for us when trying to bring files in from the host to the container during runtime. A different `-v` syntax solves this problem.
  
  Imagine I have a subfolder in my project directory `./src` that I wish to sync to `/src` inside the container. This command does the trick:
  
  ```
  docker run -it -v $(pwd)/src:/src myTest
  
  ```
  
  Both sides of the `:` character expects an absolute path. Left side being an absolute path on the host machine, right side being an absolute path inside the container.
  
  We run this command:
  
  ```
  docker run -v $(pwd)/src:/src myTest
  
  ```
  
  **Is the specification purely informational?**
  
  No, it does mount a volume, it's similar to `-v /var/www` you just don't specify a mount point in the host machine, so docker will take care of it.
  
  **What are the (dis)advantages of (not) specifying volumes?**  
  **Why and in which cases should I use VOLUME and when shouldn't I?**
  
  It's probably a best practice to never use `VOLUME`.  
  The first reason we have already identified: We can not specify the host path.  
  The second reason is people might forget to use the `--rm` option when running the container, you will end up with a couple of unused volumes and it might be a daunting task to figure out which of all anonymous volumes are safe to remove
  
  **What about files that may optionally be mounted? Do they count as volumes in that case, too?**
  
  In this case you don't need volumes; mapping a single file does not make sense, I would use `ADD` or `COPY` inside the dockerfile.
  
  
  ---
  
  