Docker Anonymous Volumes
Asked Answered
E

5

31

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
Ecumenicity answered 7/7, 2017 at 17:25 Comment(0)
K
22

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.

Kyleekylen answered 11/5, 2018 at 19:55 Comment(1)
Can't name a volume with a DockerfileHuntsman
I
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.

Invalid answered 7/7, 2017 at 18:12 Comment(3)
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.Uncivil
@JeffRSon: Have you found an answer to your question? What is a legitimate and useful usage of anonymous volumes?Byelostok
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.Fortran
Y
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.

Yeast answered 16/3, 2021 at 20:20 Comment(0)
F
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.

Fortran answered 26/11, 2021 at 13:43 Comment(0)
B
2

I'm using an anonymous volume to NOT reflect node_modules between the host and the container. The node_modules are managed by pnpm and thus will not work on both windows (here as host) and linx (here as container) at the same time. Thus it comes in extremely handy for me (and probably for the docker engine too ;)) to have the code reflected in both directions automatically and have node_modules isolated.

Here is my docker-compose.yml

version: '3.8'

services:
  container:
    image: my-image:dev
    container_name: my-container
    build: .
    volumes:
      - .:/app
      # Making an anonymous volume for node_modules
      # so that we can overwrite it in the container
      # and the changes will never be reflected 
      # on the host
      - /app/node_modules
    working_dir: /app
    # We want to keep this container running
    # to be able to execute commands in it during development
Barnebas answered 22/3 at 11:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.