docker compose volume type - bind vs volume

42,348

Solution 1

When bind mounts are files coming from your host machine, volumes are something more like the of docker.

  • Bind mounts are files mounted from your host machine (the one that runs your docker daemon) onto your container.
  • Volumes are like storage spaces totally managed by docker.
    You will find, in the literature, two types of volumes:
    • named volumes (you provide the name of it)
    • anonymous volumes (usual UUID names from docker, like you can find them on container or untagged images)

Those volumes come with their own set of docker commands; you can also consult this list via

docker volume --help

You can see your existing volumes via

docker volume ls

You can create a named volume via

docker volume create my_named_volume

But you can also create a volume via a docker-compose file

version: "3.3"

services:
  mysql:
    image: mysql
    volumes:
      - type: volume
          source: db-data
          target: /var/lib/mysql/data

volumes:
  db-data:

Where this is the part saying please docker, mount me the volume named db-data on top of the container directory /var/lib/mysql/data

- type: volume
    source: db-data
    target: /var/lib/mysql/data

And this is the part saying to docker please create me a volume named db-data

volumes:
  db-data:

Docker documentation about the three mount types:

Solution 2

If I understood you correctly, you're asking in other words: What is the difference between Volumes and bind mounts?

Differences in management and isolation on the host

Bind mounts exist on the host file system and being managed by the host maintainer.
Applications / processes outside of Docker can also modify it.

Volumes can also be implemented on the host, but Docker will manage them for us and they can not be accessed outside of Docker.

Volumes are a much wider solution

Although both solutions help us to separate the data lifecycle from containers, by using Volumes you gain much more power and flexibility over your system.

With Volumes we can design our data effectively and decouple it from the host and other parts of the system by storing it dedicated remote locations (Cloud for example) and integrate it with external services like backups, monitoring, encryption and hardware management.

More Volumes advantages over bind mounts:

  1. No host concerns.
  2. Can be managed using Docker CLI.
  3. Volumes can save you some uid/gid issues related permissions which occur in cases like when a container user's uid does not match the host gid.
  4. A new volume’s contents can be pre-populated by a container.

Examples

Lets take 2 scenarios.

Case 1: Web server.
We want to provide our web server a configuration file that might change frequently.
For example: exposing ports according to the current environment.
We can rebuild the image each time with the relevant setup or create 2 different images for each environment. Both of this solutions aren’t very efficient.

With Bind mounts Docker mounts the given source directory into a location inside the container.
(The original directory / file in the read-only layer inside the union file system will simply be overridden).

For example - binding a dynamic port to nginx:

version: "3.7"
services:
  web:
    image: nginx:alpine
    volumes:
     - type: bind #<-----Notice the type
       source: ./mysite.template
       target: /etc/nginx/conf.d/mysite.template
    ports:
     - "9090:8080"
    environment:
     - PORT=8080
    command: /bin/sh -c "envsubst < /etc/nginx/conf.d/mysite.template > 
        /etc/nginx/conf.d/default.conf && exec nginx -g 'daemon off;'"

(*) Notice that this example could also be solved using Volumes.

Case 2 : Databases.
Docker containers do not store persistent data: any data that will be written to the writable layer in container’s union file system will be lost once the container stop running.

But what if we have a database running on a container, and the container stops - that means that all the data will be lost?

Volumes to the rescue.
Those are named file system trees which are managed for us by Docker.

For example - persisting Postgres SQL data:

services:    
  db:
    image: postgres:latest
    volumes:
      - "dbdata:/var/lib/postgresql/data"
    volumes:
     - type: volume #<-----Notice the type
       source: dbdata
       target: /var/lib/postgresql/data
volumes:
  dbdata:

Notice that in this case, for named volumes, the source is the name of the volume (For anonymous volumes, this field is omitted).

Solution 3

Feature Bind Volume                                 
Internal soul Bind mounts attach a user-specified location on host filesystem to a specific point in a container file tree. Volume attach with disk storage on the host filesystem or cloud storage.
command --mount type=bind,src="",dst="" Docker CLI
docker volume command
Dependency dependent on location on to the host filesystem. Container-independent data management
Separation of concerns No Yes
Conflict with other containers Yes Example: multiple instances of Cassandra that all use the same host location as a bind mount for data storage. In that case, each of the instances would compete for the same set of files. Without other tools such as file locks, that would likely result in corruption of the database. No. By default, Docker creates volumes by using the local volume plugin.
When to choose 1- Bind mounts are useful when the host provides a file or directory that is needed by a program running in a container, or when that containerized program produces a file or log that is processed by users or programs running outside containers.
2- appropriate tools for workstations, machines with specialized concerns
3- systems with more traditional configuration management tooling.
Working with Persistent storage
1. Databases
2. Cloud storage
When not to choose Better to avoid these kinds of specific bindings in generalized platforms or hardware pools. To be written
Share:
42,348

Related videos on Youtube

Efrat Levitan
Author by

Efrat Levitan

Ask questions; don't make assumptions.

Updated on July 09, 2022

Comments

  • Efrat Levitan
    Efrat Levitan almost 2 years

    TLDR

    In docker-compose, whats the difference between

    volumes:
        - type: volume
          source: mydata
          target: /data
    

    and

    volumes:
        - type: bind
          source: mydata
          target: /data
    

    ?

    The question in long:

    When you specify the volumes option in your docker-compose file, you can use the long-syntax style

    According to the docs, the type option accepts 3 different values: volume, bind and tmpfs:

    I understand the tmpfs option - it means that the volume will not be saved after the container is down..

    But I fail to find any reference in the docs about the difference between the other 2 options: bind and volume, could someone enlighten me about that?

  • Efrat Levitan
    Efrat Levitan about 5 years
    thanks, its getting cleared now. can you also tell me, when i use the short-syntax style in my volume (path:path), to which option does the type defaults to?
  • β.εηοιτ.βε
    β.εηοιτ.βε about 5 years
    None. Or actually, both. Docker is getting clever about it. If it gets a /pat/to/file it will be a bind. If it gets a ./relative/path/to/file also, if it is just a name then docker understand it is a volume