Docker Containers and Storage volumes
When the default disk space allocated to a container is not appropriate for the job at hand, In these cases we need storage that can persist between container deployments.
In such case we use --mount
or -v
option.
Volumes
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.
Volumes have several advantages over bind mounts:
- Volumes are easier to back up or migrate than bind mounts.
- You can manage volumes using Docker CLI commands or the Docker API.
- Volumes work on both Linux and Windows containers.
- Volumes can be more safely shared among multiple containers.
- Volume drivers let you store volumes on remote hosts or cloud providers, to encrypt the contents of volumes, or to add other functionality.
- New volumes can have their content pre-populated by a container.
- Volumes on Docker Desktop have much higher performance than bind mounts from Mac and Windows hosts.
In addition, volumes are often a better choice than persisting data in a container’s writable layer, because a volume doesn’t increase the size of the containers using it, and the volume’s contents exist outside the lifecycle of a given container.
If your container generates non-persistent state data, consider using a tmpfs mount to avoid storing the data anywhere permanently, and to increase the container’s performance by avoiding writing into the container’s writable layer.
We can specify the volume by using --volume
or -v
option.
- This option consists of three fields, separated by colon characters
(:)
. The fields must be in the correct order, and the meaning of each field isn’t immediately obvious. - In the case of named volumes, the first field is the name of the volume, and is unique on a given host machine. For anonymous volumes, the first field is omitted.
- The second field is the path where the file or directory are mounted in the container.
- The third field is optional, and is a comma-separated list of options, such as
ro
.
Bind mounts
docker container run --rm --it \
--mount=type=bind,target=/mnt/session_data,source=/data \
ubuntu:latest /bin/bash
- When you use a bind mount, a file or directory on the host machine is mounted into a container.
- The file or directory is referenced by its absolute path on the host machine.
- Neither the host mount point nor the mount point in the container needs to preexist for this command to work properly. If the host mount point does not exists, then it will be created as a directory.
You can read more about the bind mount here.
According to official website:
New users should use the
--mount
syntax. Experienced users may be more familiar with the-v
or--volume
syntax, but are encouraged to use--mount
, because research has shown it to be easier to use.
--mount
: Consists of multiple key-value pairs, separated by commas and each consisting of a<key>=<value>
tuple.- The
source
of the mount. For bind mounts, this is the path to the file or directory on the Docker daemon host. May be specified assource
orsrc
. - The
destination
takes as its value the path where the file or directory is mounted in the container. May be specified asdestination
,dst
, ortarget
. - The
readonly
option, if present, causes the bind mount to be mounted into the container as read-only. - The
bind-propagation
option, if present, changes the bind propagation. May be one ofrprivate
,private
,rshared
,shared
,rslave
,slave
. - The –mount flag does not support z or Z options for modifying selinux labels.
- If you use
--mount
to bind-mount a file or directory that does not yet exist on the Docker host, Docker does not automatically create it for you, but generates an error.- Use
docker inspect <container_name>
to verify that the bind mount was created correctly.- If you
bind-mount
a directory into a non-empty directory on the container, the directory’s existing contents are obscured by the bind mount. This can be beneficial, such as when you want to test a new version of your application without building a new image. However, it can also be surprising and this behavior differs from that of docker volumes.
By default bind-mount
has read and write permission, but we can give the mount location read only access.
docker run -d \
-it \
--name devtest \
--mount type=bind,source="$(pwd)"/target,target=/app,readonly \
nginx:latest