By default all files created inside a container are stored on a writable container layer. This means that:
- The data doesn’t persist when that container no longer exists, and it can be difficult to get the data out of the container if another process needs it.
- A container’s writable layer is tightly coupled to the host machine where the container is running. You can’t easily move the data somewhere else.
- Writing into a container’s writable layer requires a storage driver to manage the filesystem. The storage driver provides a union filesystem, using the Linux kernel. This extra abstraction reduces performance as compared to using data volumes, which write directly to the host filesystem.
Docker has two options for containers to store files in the host machine, so that the files are persisted even after the container stops: volumes, and bind mounts.
- Volumes are stored in a part of the host filesystem which is managed by Docker (/var/lib/docker/volumes/ on Linux). Non-Docker processes should not modify this part of the filesystem. Volumes are the best way to persist data in Docker.
- Bind mounts may be stored anywhere on the host system. They may even be important system files or directories. Non-Docker processes on the Docker host or a Docker container can modify them at any time.
- tmpfs mounts are stored in the host system’s memory only, and are never written to the host system’s filesystem.
Volumes: Created and managed by Docker. You can create a volume explicitly using the docker volume create command, or Docker can create a volume during container or service creation. When you create a volume, it is stored within a directory on the Docker host. When you mount the volume into a container, this directory is what is mounted into the container.
Bind mounts: Available since the early days of Docker. Bind mounts have limited functionality compared to volumes. 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 full path on the host machine. The file or directory does not need to exist on the Docker host already.
Choose the -v or –mount flag
In general, --mount is more explicit and verbose. The biggest difference is that the -v syntax combines all the options together in one field, while the --mount syntax separates them. Here is a comparison of the syntax for each flag.
If you need to specify volume driver options, you must use --mount.
-vor--volume: Consists of three fields, separated by colon characters (:). The fields must be in the correct order, and the meaning of each field is not 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. These options are discussed below.
--mount: Consists of multiple key-value pairs, separated by commas and each consisting of a<key>=<value>tuple. The--mountsyntax is more verbose than-vor--volume, but the order of the keys is not significant, and the value of the flag is easier to understand.- The
typeof the mount, which can be bind, volume, or tmpfs. This topic discusses volumes, so the type is alwaysvolume. - The
sourceof the mount. For named volumes, this is the name of the volume. For anonymous volumes, this field is omitted. May be specified assourceorsrc. - The
destinationtakes as its value the path where the file or directory is mounted in the container. May be specified asdestination,dst, ortarget. - The
readonlyoption, if present, causes the bind mount to be mounted into the container as read-only. - The
volume-optoption, which can be specified more than once, takes a key-value pair consisting of the option name and its value.
- The
Differences between -v and --mount behavior
As opposed to bind mounts, all options for volumes are available for both --mount and -v flags.
When using volumes with services, only --mount is supported.
Create and manage volumes
Unlike a bind mount, you can create and manage volumes outside the scope of any container.
- Create a volume:
# docker volume create my-vol
- List volumes:
# docker volume ls
local my-vol
- Inspect a volume:
# docker volume inspect my-vol
- Remove a volume:
# docker volume rm my-vol
- Example of mount:
#docker run-d--nametest--mountsource=myvol,target=/app\ nginx:latest
- Example of volume mounts:
#docker run-d--nametest-vmyvol:/appnginx:latest
- To remove volume:
Stop and remove the container, and remove the volume. Volume removal is a separate step.
# docker container stop nginxtest
# docker container rm nginxtest
# docker volume rm nginx-vol
Start a service with volumes
#docker service create-d--replicas=4--nametest-service\ --mountsource=myvol,target=/testappnginx:latest
Remove volumes
A Docker data volume persists after a container is deleted. There are two types of volumes to consider:
- Named volumes have a specific source from outside the container, for example
awesome:/car. - Anonymous volumes have no specific source so when the container is deleted, instruct the Docker Engine daemon to remove them.
Remove anonymous volumes
To automatically remove anonymous volumes, use the --rm option. For example, this command creates an anonymous /foo volume. When the container is removed, the Docker Engine removes the /foo volume but not the awesome volume.
# docker run --rm -v /doo -v awesome:/car busytool top
Remove all volumes
To remove all unused volumes and free up space:
# docker volume prune
References:
- https://docs.docker.com
- from Miscellaneous technical websites.
