27

I've seen Docker volume definitions in docker-compose.yml files like so:

-v /path/on/host/modules:/var/www/html/modules

I noticed that Drupal's official image, their docker-compose.yml file is using anonymous volumes.

Notice the comments:

volumes:
  - /var/www/html/modules
  - /var/www/html/profiles
  - /var/www/html/themes
  # this takes advantage of the feature in Docker that a new anonymous
  # volume (which is what we're creating here) will be initialized with the
  # existing content of the image at the same location
  - /var/www/html/sites

Is there a way to associate an anonymous volume with a path on the host machine after the container is running? If not, what is the point of having anonymous volumes?

Full docker-compose.yml example:

version: '3.1'

services:

  drupal:
    image: drupal:8.2-apache
    ports:
      - 8080:80
    volumes:
      - /var/www/html/modules
      - /var/www/html/profiles
      - /var/www/html/themes
      # this takes advantage of the feature in Docker that a new anonymous
      # volume (which is what we're creating here) will be initialized with the
      # existing content of the image at the same location
      - /var/www/html/sites
    restart: always

  postgres:
    image: postgres:9.6
    environment:
      POSTGRES_PASSWORD: example
    restart: always
Mostafa Hussein
  • 11,063
  • 3
  • 36
  • 61
Raphael Rafatpanah
  • 19,082
  • 25
  • 92
  • 158

4 Answers4

19

Adding a bit more info in response to a follow-up question/comment from @JeffRSon asking how anonymous volumes add flexibility, and also to answer this question from the OP:

Is there a way to associate an anonymous volume with a path on the host machine after the container is running? If not, what is the point of having anonymous volumes?

TL;DR: You can associate a specific anonymous volume with a running container via a 'data container', but that provides flexibility to cover a use case that is now much better served by the use of named volumes.

Anonymous volumes were helpful before the addition of volume management in Docker 1.9. Prior to that, you didn't have the option of naming a volume. With the 1.9 release, volumes became discrete, manageable objects with their own lifecycle.

Before 1.9, without the ability to name a volume, you had to reference it by first creating a data container

docker create -v /data --name datacontainer mysql

and then mounting the data container's anonymous volume into the container that needed access to the volume

docker run -d --volumes-from datacontainer --name dbinstance mysql

These days, it's better to use named volumes since they are much easier to manage and much more explicit.

BitMask777
  • 2,543
  • 26
  • 36
8

Anonymous volumes are equivalent to having these directories defined as VOLUME's in the image's Dockerfile. In fact, directories defined as VOLUME's in a Dockerfile are anonymous volumes if they are not explicitly mapped to the host.

The point of having them is added flexibility.

PD: Anonymous volumes already reside in the host somewhere in /var/lib/docker (or whatever directory you configured). To see where they are:

docker inspect --type container -f '{{range $i, $v := .Mounts }}{{printf "%v\n" $v}}{{end}}' $CONTAINER

Note: Substitute $CONTAINER with the container's name.

Ricardo Branco
  • 5,740
  • 1
  • 21
  • 31
  • 17
    How do they add flexibility? I understand anonymous volumes in general, but I don't understand the use, as every "docker run" creates new volume. – JeffRSon Apr 28 '18 at 11:47
  • @JeffRSon: Have you found an answer to your question? What is a legitimate and useful usage of anonymous volumes? – cherouvim Feb 03 '21 at 13:13
  • 4
    I'd say `json` is more readable than `printf`. We can even take it a bit further, `docker inspect -f '{{json .Mounts}}' "$CONTAINER" | jq`. And there's also `%+v`. – x-yuri Nov 26 '21 at 13:23
8

One possible usecase of anonymous volumes in these days is in combination with Bind Mounts. When you want to bind some folder but without any specific subfolders. These specific subfolders should be then set as named or anonymous volumes. It will guarantee that these subfolders will be present in your container folder which is bounded outside the container but you do not have to have it in your bound folder on the host machine at all.

For example you can have your frontend NodeJS project built in container where is needed node_modules folder for it but you dont need this folder for your coding at all. You can then map your project folder to some folder outside the container and set the node_modules folder as an anonymous volume. Node_modules folder will be present in the container all the time even if you do not have it on the host machine in your working folder.

3

Not sure why Drupal developers suggest such settings. Anyways, I can think of two differences:

  1. With named volumes you have a name that suggests to which project it belongs.

  2. After docker-compose down && docker-compose up -d a new empty anonymous volume gets attached to the container. (But the old one doesn't disappear. docker doesn't delete volumes unless you tell it to.) With named volumes you'll get the volume that was attached to the container before docker-compose down.

As such, you probably don't want to put data you don't want to lose into an anonymous volume (like db or something). Again, they won't disappear by themselves. But after docker-compose down && docker-compose up -d && docker volume prune a named volume will survive.

For something less critical (like node_modules) I don't have strong argument for or against named volumes.

Is there a way to associate an anonymous volume with a path on the host machine after the container is running?

For that you need to change the settings, e.g. /var/www/html/modules -> ./modules:/var/www/html/modules, and do docker-compose up -d. But that will turn an anonymous volume into a bind mount. And you will need to copy the data from the volume to ./modules. Similarly, you can turn an anonymous volume into a named volume.

x-yuri
  • 16,722
  • 15
  • 114
  • 161