Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Docker Compose: volumes without colon (:)

I have a docker-compose.yml file with the following:

volumes:   - .:/usr/app/   - /usr/app/node_modules 

First option maps current host directory to /usr/app, but what does the second option do?

like image 884
musicliftsme Avatar asked Sep 12 '17 00:09

musicliftsme


People also ask

Can docker compose create volumes?

We can also create a volume with Docker compose service or also specify existing volumes. For example, the following screenshot shows a 'docker-compose' file that creates a docker-compose service with a volume. As a result of the above command, a volume with the name 'myvolume' gets created.

What does colon mean in docker?

: is used to separate the host 's path from container 's path. (Each volume uses a source path for the host and a destination path for the container). :cached seems to be a caching option for docker-for-mac.

Do you need Dockerfiles with docker compose?

Docker compose uses the Dockerfile if you add the build command to your project's docker-compose. yml. Your Docker workflow should be to build a suitable Dockerfile for each image you wish to create, then use compose to assemble the images using the build command.

Can data volumes can be mounted in read only mode?

Use a read-only volume Remember that multiple containers can mount the same volume, and it can be mounted read-write for some of them and read-only for others, at the same time.


2 Answers

[Refreshing this answer since it seems others have similar questions]

There are three kinds of volumes in docker:

  • Host volumes: these map a path from the host into the container with a bind mount. They have the short syntax /path/on/host:/path/in/container. Whatever exists on the host is what will be visible in the container, there's no merging of files or initialization from the image, and uid/gid's do not get any special mapping so you need to take care to allow the container uid/gid read and write access to this location (an exception is Docker for Mac with OSXFS). If the path on the host does not exist, docker will create an empty directory as root, and if it is a file, you can mount a single file into the container this way.

  • Named volumes: these have a name, instead of a host path as the source. They have the short syntax name:/path/in/container and in a compose file, you also need to define the named volume used in containers at the top level. By default, these are also a bind mount, but to a docker specific directory under /var/lib/docker/volumes that should be considered internal. However these defaults can be changed to allow things like NFS mounts, mounting disks, or even your own bind mounts to other locations. Named volumes also have a feature in docker, when they are new or empty and first used, docker copies the contents from the image into named volume before mounting it. This includes files, directories, uid/gid owners, and permissions. After that, they behave identical to a host volume, whatever is inside the volume overlays the image location.

  • Anonymous volumes: these only have a path inside the container. They are in the form /path/in/container and docker will create a default named volume with a guid as the name. They share the behaviors of named volumes, storing files under /var/lib/docker/volumes, initializing with the contents of the image, except they have a randomly generated guid that gives you no indication of how or even if they are being used. You can mount the volume in another container and inspect the contents, or you can find the container using the volume by inspecting each container to find the guid. If you create a container with the --rm flag, anonymous volumes will also be deleted automatically.

  • tmpfs: Wait, I said 3, and this is 4? That's because tmpfs isn't considered a volume, the syntax to mount it is different. The result is a pointer to an empty in memory filesystem. This is useful if you have temporary files you don't wish to save, they are relatively small, and you either need speed or want to be sure they aren't saved to disk.

In the OP's case:

  • /usr/app is mounted from the host, commonly used for development
  • /usr/app/node_modules is an anonymous volume initialized from the image

Why do this? Likely because you do not want to modify the node_modules directory on the host, particularly if there's platform specific data and you're running on Docker desktop where it's Mac/Win on the host and Linux in the container. It's also possible there's data in the image you want to get access to within the directory structure of the other volume mount.

Are there downsides to anonymous volumes? Two that I can think of:

  • If there's anything in /usr/app/node_modules that you want to reuse in a future container, you're unlikely to find the old volume. I tend to consider any data written to these as likely lost.

  • You'll often find the volumes on the host full of guids over time, and it's unclear which are in use and which can be deleted. Unused anonymous volumes are one of several causes of excessive disk use in docker.

For more details on docker volumes, see: https://docs.docker.com/storage/


Original answer:

The second one creates an anonymous volume. It will be listed in docker volume ls with a long unique id rather than a name. Docker-compose will be able to reuse this if you update your image, but it's easy to lose track of which volume belongs to what with those names, so I recommend always giving your volume a name.

like image 185
BMitch Avatar answered Sep 21 '22 19:09

BMitch


Just to complement the accepted answer, according to Docker's Knowledge Base there are three types of volumes: host, anonymous, and named:

  • A host volume lives on the Docker host's filesystem and can be accessed from within the container. Example volume path:

    /path/on/host:/path/in/container

  • An anonymous volume is useful for when you would rather have Docker handle where the files are stored. It can be difficult, however, to refer to the same volume over time when it is an anonymous volumes. Example volume path:

    /path/in/container

  • A named volume is similar to an anonymous volume. Docker manages where on disk the volume is created, but you give it a volume name. Example volume path:

    name:/path/in/container

The path used in your example is an anonymous volume.

like image 22
Wilson Silva Avatar answered Sep 21 '22 19:09

Wilson Silva