Search code examples
dockerdocker-composecontainersbindvolumes

Mount volume from host in Dockerfile long format


When configuring a docker-compose.yml, I can easily mount a volume that maps a folder from the host machine to the container:

...
    volumes:
      - "/host/folder/:/container/folder/"
...

However, if I try to use the long syntax, that doesn't work anymore:

...
volumes:
      - type: volume
        source: /host/folder
        target: /container/folder/
...

According to the docs

source: the source of the mount, a path on the host for a bind mount, or the name of a volume defined in the top-level volumes key. Not applicable for a tmpfs mount.

So, it seems that in the long syntax I have to use the bind type to mount a host path. Does this make sense, different features according to syntax?

Furthermore, again, according to the docs,

Volumes are the preferred mechanism for persisting data generated by and used by Docker containers. While bind mounts are dependent on the directory structure and OS of the host machine, volumes are completely managed by Docker.

So, I much prefer having volumes instead of binds. Do I have to use the short syntax for that?


Solution

  • The type: field says whether it's a named volume, a bind mount, or a couple of other things. Since you're mounting a host directory, you need to specify type: bind in the extended syntax.

    volumes:
      - type: bind         # <-- not "volume"
        source: /host/folder
        target: /container/folder/
    

    according to the docs, "volumes are [...] preferred...."

    IMHO the Docker documentation is very enthusiastic about named volumes and glosses over their downsides. Since you can't access the contents of a named volume from outside of Docker, they're harder to back up and manage, and a poor match for tasks like injecting config files and reviewing logs. I would not automatically reach for a named volume because the Docker documentation suggests it's preferred.

    version: '3.8'
    services:
      some-application:
        volumes:
    
          # Use a bind mount to inject configuration files; you need to
          # directly edit them on the host
          - type: bind
            source: ./config
            target: /app/config
    
          # Use a bind mount to read back log files; you need to read them
          # on the host
          - type: bind
            source: ./log
            target: /app/data
    
          # Use a named volume for opaque application data; you do not
          # need to manipulate files on the host, and on MacOS/Windows
          # a named volume will be faster
          - type: volume
            source: app-data  # when type: volume, this is a volume name
            target: /app/data
    
          # Do not mount anything over /app or the code in the image.
    
    volumes:
      app-data: