Work with volume and bind mounts

Manage data in Docker

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. If you’re running Docker on Linux you can also use a tmpfs mount. If you’re running Docker on Windows you can also use a named pipe.

Keep reading for more information about these two ways of persisting data.

  • 默认情况下,容器内创建的所有文件都会被保存在一个可写的容器层,这就意味着:

    1. 当容器消失时,数据不会持久化,当其他进程需要此数据时,很难将该数据取出
    2. 容器的可写层和宿主机紧密结合在一起,不能随意将数据迁移到其他地方。
    3. 向容器的可写层写入数据需要使用存储驱动来管理文件系统。存储驱动使用Linux内核提供了联合的文件系统,。与data volumes可以直接写入宿主机文件系统相比,这层抽象降低了性能表现。
  • Docker提供了两种方式来实现容器文件在宿主机的存储,从而使得文件可以在容器停止后在宿主机保留下来:volumes 和bind mounts.如果是在Linux上运行Docker,也可以使用tmpfs mount的方式。如果在windows上运行docker,可以使用named pipe.

Choose the right type of mount

No matter which type of mount you choose to use, the data looks the same from within the container. It is exposed as either a directory or an individual file in the container’s filesystem.

An easy way to visualize the difference among volumes, bind mounts, and tmpfs mounts is to think about where the data lives on the Docker host.

  • 无论选择使用哪种挂载方式,在容器内部看来数据都是一样的。在容器的文件系统中都是以目录或单独的文件形式展示的。

  • 一个简单的理解中这几种不同挂载方式的方法是考虑数据在Docker宿主机上的存储位置

Work with volume and bind mounts - 图1

  • 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 : 存储在由Docker管理的部分宿主机文件系统上(在Linux的位置是/var/lib/docker/volumes/) .非Docker进程不能修改这部分的文件系统。Volumes是持久化Docker数据的最好方式
  • Bind mounts : 可以存储在宿主机的任何位置。甚至是关键的系统文件文件或路径。非Docker进程也可以随意修改这些文件。
  • tmpfs mounts:只存储在宿主机的内存中,不会写入到宿主机系统的文件系统里。

More details about mount types

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. This is similar to the way that bind mounts work, except that volumes are managed by Docker and are isolated from the core functionality of the host machine.

A given volume can be mounted into multiple containers simultaneously. When no running container is using a volume, the volume is still available to Docker and is not removed automatically. You can remove unused volumes using docker volume prune.

When you mount a volume, it may be named or anonymous. Anonymous volumes are not given an explicit name when they are first mounted into a container, so Docker gives them a random name that is guaranteed to be unique within a given Docker host. Besides the name, named and anonymous volumes behave in the same ways.

Volumes also support the use of volume drivers, which allow you to store your data on remote hosts or cloud providers, among other possibilities.

  • Volumes : 由Docker创建和管理。可以使用 docker volume create命令显示创建volume,Docker在container或service创建时叶可以自动创建volume.

  • 创建的volume会被存储在Docker host的目录内。当在一个容器中挂载此volume时,这个目录目录就是被挂载到容器中的东西。可和 bind mount的工作方式类似,除了volumes是被Docker管理并会和宿主机的核心功能隔离。

  • 给定的volumes可以被同时挂载到多个容器中。当没有容器使用这个volume时,这个volume仍可被Docker使用不会被自动删除。可以使用docker volume prune指令来手动删除volume。

  • volume可以通过具名和匿名两种方式进行挂载。匿名volumes在第一次被挂载到容器内时不会被指定显示的名字,因此Docker会随机生成一个在Docker host内唯一的名字。除名字外,具名volume和匿名volume功能一致。

  • Volumes支持使用volume驱动,允许将数据存储到远程主机或云端,以及其他可使用的选择

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. It is created on demand if it does not yet exist. Bind mounts are very performant, but they rely on the host machine’s filesystem having a specific directory structure available. If you are developing new Docker applications, consider using named volumes instead. You can’t use Docker CLI commands to directly manage bind mounts.

Bind mounts allow access to sensitive files

One side effect of using bind mounts, for better or for worse, is that you can change the host filesystem via processes running in a container, including creating, modifying, or deleting important system files or directories. This is a powerful ability which can have security implications, including impacting non-Docker processes on the host system.

  • Bind mounts:Docker早期提供的方式。Bind mounts与volumes相比功能没有那么多。当使用bind mount时,宿主机的文件或目录会被挂载到容器中。文件或路由通过它自己在宿主机上的的绝对路径提供,不需要在容器上已经存在,容器会根据需要自行进行创建。Bind mounts性能很好,但是依赖于宿主机的文件系统,有特定的目录结构。如果是创建新的Docker应用,最好考虑使用具名volume.无法使用Docker CLI工具来直接管理Bind mount.
    • !Bind mounts允许直接访问敏感文件
    • 使用bind mounts的一个副作用时,可以通过运行容器来改变宿主机的文件系统。例如增删改善重要的系统文件或目录。这是个强大的功能,可能会因此安全隐患,包括影响宿主机上非Docker的进程。

A tmpfs mount is not persisted on disk, either on the Docker host or within a container. It can be used by a container during the lifetime of the container, to store non-persistent state or sensitive information. For instance, internally, swarm services use tmpfs mounts to mount secrets into a service’s containers.

  • tmpfs mounts : 不会再磁盘上进行持久化,不管时在Docker host上还是容器内。可以在容器生命周期内使用来存储非持久化或敏感的信息,例如,swarm服务使用tmpfs来挂载服务容器内部的一些隐蔽数据。

named pipes: An npipe mount can be used for communication between the Docker host and a container. Common use case is to run a third-party tool inside of a container and connect to the Docker Engine API using a named pipe.

  • named pipes:npipe勾搭可以用于Docker host和容器之间的通信。常见情形是在Docker内运行一个第三方工具,使用具名管道连接到Docker引擎的API

Bind mounts and volumes can both be mounted into containers using the -v or --volume flag, but the syntax for each is slightly different. For tmpfs mounts, you can use the --tmpfs flag. We recommend using the --mount flag for both containers and services, for bind mounts, volumes, or tmpfs mounts, as the syntax is more clear.

  • Bind mounts 和volume都可以通过使用-v--volume来进行挂载,但是语法略微不同。可以使用--tmpfs来实现tmpfs的挂载。推荐在container和service中都使用--mounts来实现bind mount,volume或tmpfs的挂载,因为这样语法会更加清晰。

Good use case for volumes

Volumes are the preferred way to persist data in Docker containers and services. Some use cases for volumes include:

  • Sharing data among multiple running containers. If you don’t explicitly create it, a volume is created the first time it is mounted into a container. When that container stops or is removed, the volume still exists. Multiple containers can mount the same volume simultaneously, either read-write or read-only. Volumes are only removed when you explicitly remove them.
  • When the Docker host is not guaranteed to have a given directory or file structure. Volumes help you decouple the configuration of the Docker host from the container runtime.
  • When you want to store your container’s data on a remote host or a cloud provider, rather than locally.
  • When you need to back up, restore, or migrate data from one Docker host to another, volumes are a better choice. You can stop containers using the volume, then back up the volume’s directory (such as /var/lib/docker/volumes/<volume-name>).
  • When your application requires high-performance I/O on Docker Desktop. Volumes are stored in the Linux VM rather than the host, which means that the reads and writes have much lower latency and higher throughput.
  • When your application requires fully native file system behavior on Docker Desktop. For example, a database engine requires precise control over disk flushing to guarantee transaction durability. Volumes are stored in the Linux VM and can make these guarantees, whereas bind mounts are remoted to macOS or Windows, where the file systems behave slightly differently.
  • Volume 是Docker容器和服务器进行持久化的推荐方式。一些使用volume 的场景包括:

    1. 在多个运行的容器中保存数据。如果没有显示的创建,容器会在创建的时候自动生成一个volume,当容器停止或被移除时,voulme仍然存在。多个容器可以同时挂载同一个volume,不管时读写或制度模式。volume只会在显示删除后被移除。
    2. 无法保证Docker host对给定文件/目录有权限时.Volumes可以让Docker host和容器运行解耦。
    3. 当需要将容器的数据存储到远程主机或云上,而不是本地时。
    4. 当需要备份,回复或将数据从一个Docker转移到另一个时。Volume是最好的选择。可以让容器停止使用volume,之后备份volume的目录(例如/var/lib/docker/volumes/<volumes-name)
    5. 当Docker Desktop上的应用需要需要高性能IO时。Volumes被存储在Linux VM而不是主机,以为者读写操作有着更低的延迟以及更高的吞吐量。
    6. 当Docker Desktop上的应用程序需要完全原生的文件系统时。例如,一个数据库引擎需要对磁盘刷新精确掌控来保证事务的可持续性。Volumes被存储的Linux VM上,可以保证这些功能,同时bind mounts可以远程到文件系统表现不同的Windows和macOS上。

Good use case of bind mounts

In general, you should use volumes where possible. Bind mounts are appropriate for the following types of use case:

  • Sharing configuration files from the host machine to containers. This is how Docker provides DNS resolution to containers by default, by mounting /etc/resolv.conf from the host machine into each container.

  • Sharing source code or build artifacts between a development environment on the Docker host and a container. For instance, you may mount a Maven target/ directory into a container, and each time you build the Maven project on the Docker host, the container gets access to the rebuilt artifacts.
    If you use Docker for development this way, your production Dockerfile would copy the production-ready artifacts directly into the image, rather than relying on a bind mount.

  • When the file or directory structure of the Docker host is guaranteed to be consistent with the bind mounts the containers require.

  • 一般情况下应该尽量使用volumes。Bind mount仅适用于以下情形。

    1. 在宿主机和容器之间共享数据。这也是Docker向容器提供DNS的默认方式,通过从宿主机上挂载/etc/resolv.conf到每个容器上。

    2. 在Docker host上的研发环境和容器中共享源代码或构建文件时。例如,可以向容器中添加Maven target/目录,并且每次在Docker host上构建Maven项目时,容器都可以访问重建的产品。
      如果以这种方式来使用Docker进行开发,Dockerfile会直接复制已经产生的构建文件到image中,而不是依靠bind mount.

  • 当Docker host中的文件或目录结构的和容器需求能够保证完全一致的时候。

Good ues cases for tmpfs mounts

tmpfs mounts are best used for cases when you do not want the data to persist either on the host machine or within the container. This may be for security reasons or to protect the performance of the container when your application needs to write a large volume of non-persistent state data.

  • tmpfs mounts用于不想让数据在宿主机或容器内持久化的情况。可能是处于安全性考虑或考虑容器的性能,当你的应用应用需要写入大量volume为未持久化的状态数据时。

Tips for using bind mounts or volumes

If you use either bind mounts or volumes, keep the following in mind:

  • If you mount an empty volume into a directory in the container in which files or directories exist, these files or directories are propagated (copied) into the volume. Similarly, if you start a container and specify a volume which does not already exist, an empty volume is created for you. This is a good way to pre-populate data that another container needs.
  • If you mount a bind mount or non-empty volume into a directory in the container in which some files or directories exist, these files or directories are obscured by the mount, just as if you saved files into /mnt on a Linux host and then mounted a USB drive into /mnt. The contents of /mnt would be obscured by the contents of the USB drive until the USB drive were unmounted. The obscured files are not removed or altered, but are not accessible while the bind mount or volume is mounted.
  • 在使用bind mounts或volumes时,牢记以下内容:

    1. 当挂载空的volume的容器的目录中时,如果容器背身的文件和目录非空,这些文件、目录会被传播(复制)到volume中。同样的,当你启动一个容器并指定一个不存的volume时,一个空的volume为创建。这是预传播其他容器需要的数据好的方法。
    2. 如果在已经存在某些文件、目录的容器上挂载bind mount或非空的volume,这些文件对挂载时不可见的,就像在Linux中将文件存储到/mnt,之后将一个USB驱动挂载到/mnt上。/mnt下的内容会对USB 驱动不可知,直到USB 驱动被解除挂载。不可见的文件不会被移除或变更,但是在bind mount或volume挂载期间时不可访问的。

Use 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 是持久化Docker容器产生和需要使用的数据的推荐方式。bind mounts依赖于宿主机系统以及目录结构。volumes完全由docker管理。volumes对比bind mount有以下几点优势:
  • 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.
  • volumes更容易被备份和迁移
  • 可以使用Docker CLI或Docker API来管理volumes
  • volumes在Linux或window容器内都可以运行
  • volumes在多个容器的环境下更安全
  • volumes的驱动可以让你将volumes存储在远程的主机或云端上,对volume的内容进行加密或者添加其他功能
  • 新的volumes可以将自己的内容提前传播到容器中。
  • 在mac和windows宿主机上,docker桌面版的volumes性能会比bind mount更好

In addition, volumes are often a better choice than persisting data in a container’s writable layer, because a volume does not increase the size of the containers using it, and the volume’s contents exist outside the lifecycle of a given container.

  • 总之,volumes在通常情况下会比在容器可写层持久化数据更好,因为一个volumes不会增加容器使用它的大小,并且volumes的声明周期比给定容器的声明周期长。

Work with volume and bind mounts - 图2

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.

Volumes use rprivate bind propagation, and bind propagation is not configurable for volumes.

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.

-v or --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 --mount syntax is more verbose than -v or --volume, but the order of the keys is not significant, and the value of the flag is easier to understand.

  • The type of the mount, which can be bind, volume, or tmpfs. This topic discusses volumes, so the type is always volume.
  • The source of the mount. For named volumes, this is the name of the volume. For anonymous volumes, this field is omitted. May be specified as source or src.
  • The destination takes as its value the path where the file or directory is mounted in the container. May be specified as destination, dst, or target.
  • The readonly option, if present, causes the bind mount to be mounted into the container as read-only.
  • The volume-opt option, which can be specified more than once, takes a key-value pair consisting of the option name and its value.

Escape values from outer CSV parser

If your volume driver accepts a comma-separated list as an option, you must escape the value from the outer CSV parser. To escape a volume-opt, surround it with double quotes (") and surround the entire mount parameter with single quotes (').

For example, the local driver accepts mount options as a comma-separated list in the o parameter. This example shows the correct way to escape the list.

  1. $ docker service create \
  2. --mount 'type=volume,src=<VOLUME-NAME>,dst=<CONTAINER-PATH>,volume-driver=local,volume-opt=type=nfs,volume-opt=device=<nfs-server>:<nfs-path>,"volume-opt=o=addr=<nfs-address>,vers=4,soft,timeo=180,bg,tcp,rw"'
  3. --name myservice \
  4. <IMAGE>

The examples below show both the --mount and -v syntax where possible, and --mount is presented first.

Difference 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

  • Inspect a volume

    1. $ docker volume inspect my-vol
    2. [
    3. {
    4. "Driver": "local",
    5. "Labels": {},
    6. "Mountpoint": "/var/lib/docker/volumes/my-vol/_data",
    7. "Name": "my-vol",
    8. "Options": {},
    9. "Scope": "local"
    10. }
    11. ]
  • Remove a volume :
    $ docker volume rm my-vol

Start a container with a volume

If you start a container with a volume that does not yet exist, Docker creates the volume for you. The following example mounts the volume myvol2 into /app/ in the container.

The -v and --mount examples below produce the same result. You can’t run them both unless you remove the devtest container and the myvol2 volume after running the first one.

  1. $ docker run -d \
  2. --name devtest \
  3. --mount source=myvol2,target=/app \
  4. nginx:latest

Use docker inspect devtest to verify that the volume was created and mounted correctly. Look for the Mounts section:

  1. "Mounts": [
  2. {
  3. "Type": "volume",
  4. "Name": "myvol2",
  5. "Source": "/var/lib/docker/volumes/myvol2/_data",
  6. "Destination": "/app",
  7. "Driver": "local",
  8. "Mode": "",
  9. "RW": true,
  10. "Propagation": ""
  11. }
  12. ],

This shows that the mount is a volume, it shows the correct source and destination, and that the mount is read-write.

Stop the container and remove the volume. Note volume removal is a separate step.

```bash $ docker container stop devtest

$ docker container rm devtest

$ docker volume rm myvol2

  1. <a name="1517e888"></a>
  2. ## Use a volume with docker-compose
  3. <a name="b375c0cd"></a>
  4. ## Start a service with volumes
  5. <a name="e5fb0462"></a>
  6. ## Populate a volume using a container
  7. > If you start a container which creates a new volume, as above, and the container has files or directories in the directory to be mounted (such as `/app/` above), the directory’s contents are copied into the volume. The container then mounts and uses the volume, and other containers which use the volume also have access to the pre-populated content.
  8. <a name="f079e1f3"></a>
  9. ## Use a read-only volume
  10. <a name="389f237f"></a>
  11. ## Share data among machines
  12. > When building fault-tolerant applications, you might need to configure multiple replicas of the same service to have access to the same files.
  13. - 当构建容错应用时,可能需要配置多个服务的配置来访问同一份文件。
  14. ![](Work%20with%20volume%20and%20bind%20mounts.assets/chrome_EOSiEtBzTf.png#alt=chrome_EOSiEtBzTf)
  15. > There are several ways to achieve this when developing your applications. One is to add logic to your application to store files on a cloud object storage system like Amazon S3. Another is to create volumes with a driver that supports writing files to an external storage system like NFS or Amazon S3.
  16. > Volume drivers allow you to abstract the underlying storage system from the application logic. For example, if your services use a volume with an NFS driver, you can update the services to use a different driver, as an example to store data in the cloud, without changing the application logic.
  17. - 在应用开发时,有还佛方法来实现这个功能。其中一种时向应用中添加逻辑来在云服务中存储消息。另一种时使用驱动来创建volume,支持写文件到外部存储上去。
  18. - volumes驱动允许将低层的存储系统从应用层面抽象出来。例如,如果你的服务使用了NFS驱动的volume,就可以使用不同的驱动来更新服务,在云上存储也是一样的,不需要改变应用的逻辑。
  19. <a name="b23dc619"></a>
  20. ## Use a volume driver
  21. > When you create a volume using `docker volume create`, or when you start a container which uses a not-yet-created volume, you can specify a volume driver. The following examples use the `vieux/sshfs` volume driver, first when creating a standalone volume, and then when starting a container which creates a new volume.
  22. - 在使用`docker volume create`或启动未指定volume的容器时,可以声明容器使用的驱动。以下例如使用了vieux/sshfs容器驱动,第一次用在创建独立的volume,之后在启动容器时创建新的volume.
  23. <a name="9e04b95e"></a>
  24. ### Inital set-up
  25. > This example assumes that you have two nodes, the first of which is a Docker host and can connect to the second using SSH.
  26. > On the Docker host, install the `vieux/sshfs` plugin:
  27. > ```bash
  28. $ docker plugin install --grant-all-permissions vieux/sshfs

Create a volume using a volume driver

This example specifies a SSH password, but if the two hosts have shared keys configured, you can omit the password. Each volume driver may have zero or more configurable options, each of which is specified using an -o flag.

$ docker volume create --driver vieux/sshfs \
  -o sshcmd=test@node2:/home/test \
  -o password=testpassword \
  sshvolume

Start a container which creates a volume using a volume driver

This example specifies a SSH password, but if the two hosts have shared keys configured, you can omit the password. Each volume driver may have zero or more configurable options. If the volume driver requires you to pass options, you must use the --mount flag to mount the volume, rather than -v.

$ docker run -d \
  --name sshfs-container \
  --volume-driver vieux/sshfs \
  --mount src=sshvolume,target=/app,volume-opt=sshcmd=test@node2:/home/test,volume-opt=password=testpassword \
  nginx:latest

Create a service which creates an NFS volume

This example shows how you can create an NFS volume when creating a service. This example uses 10.0.0.10 as the NFS server and /var/docker-nfs as the exported directory on the NFS server. Note that the volume driver specified is local.

NFSV3

$ docker service create -d \
  --name nfs-service \
  --mount 'type=volume,source=nfsvolume,target=/app,volume-driver=local,volume-opt=type=nfs,volume-opt=device=:/var/docker-nfs,volume-opt=o=addr=10.0.0.10' \
  nginx:latest

Backup,restore,or migrate data volumes

Use bind mount

Bind mounts have been around 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 absolute path on the host machine. By contrast, when you use a volume, a new directory is created within Docker’s storage directory on the host machine, and Docker manages that directory’s contents.

The file or directory does not need to exist on the Docker host already. It is created on demand if it does not yet exist. Bind mounts are very performant, but they rely on the host machine’s filesystem having a specific directory structure available. If you are developing new Docker applications, consider using named volumes instead. You can’t use Docker CLI commands to directly manage bind mounts.

  • Bind mount 在Docker早期就出现了。Bind mounts 和volume对比功能比较有限。当使用bind mount时,在宿主机上的文件或目录会被挂载到容器中。文件或目录是由自身在宿主机上的绝对路径引用的。与此相反,当使用volume时,在宿主机的Docker存储目录下会新建一个目录。
  • 文件或目录不需要在已经在Docker host上存在。如果未存在会根据需要进行创建。bind mount很高效,但依赖与宿主机的文件系统由特定可用的目录结构。如果在开发新的容器应用,应该考虑使用命名volumes。不能直接通过Docker CLI命令来管理bind mount.

Work with volume and bind mounts - 图3

Choose the -v or —moubt 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.

  • 一般来说,--mount更加显式并且带有回复信息。最大的区别在于-v语法在一个字段里柔和了所有的选项 ,--mount语言则将这些选项分隔开。以下有两种用法的对比

Tip: 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.

  • -v or --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 bind mounts, the first field is the path to the file or directory on the host machine.

  • The second field is the path where the file or directory is mounted in the container.
  • The third field is optional, and is a comma-separated list of options, such as ro, z, and Z. These options are discussed below

  • --mount: Consists of multiple key-value pairs, separated by commas and each consisting of a <key>=<value> tuple. The --mount syntax is more verbose than -v or --volume, but the order of the keys is not significant, and the value of the flag is easier to understand.

    • The type of the mount, which can be bind, volume, or tmpfs. This topic discusses bind mounts, so the type is always bind.
    • 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 as source or src.
    • The destination takes as its value the path where the file or directory is mounted in the container. May be specified as destination, dst, or target.
    • 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 of rprivate, private, rshared, shared, rslave, slave.
    • The --mount flag does not support z or Z options for modifying selinux labels.

Difference between -v and —mount behavior

If you use -v or --volume to bind-mount a file or directory that does not yet exist on the Docker host, -v creates the endpoint for you. It is always created as a directory.

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.

Start a Container with a bind mount

Consider a case where you have a directory source and that when you build the source code, the artifacts are saved into another directory, source/target/. You want the artifacts to be available to the container at /app/, and you want the container to get access to a new build each time you build the source on your development host. Use the following command to bind-mount the target/ directory into your container at /app/. Run the command from within the source directory. The $(pwd) sub-command expands to the current working directory on Linux or macOS hosts.

The --mount and -v examples below produce the same result. You can’t run them both unless you remove the devtest container after running the first one.

Mount into a non-empty directory on the container

If you bind-mount 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.

This example is contrived to be extreme, but replaces the contents of the container’s /usr/ directory with the /tmp/ directory on the host machine. In most cases, this would result in a non-functioning container.

Use a read-only bind mount

Configure bind propagation

Bind propagation defaults to rprivate for both bind mounts and volumes. It is only configurable for bind mounts, and only on Linux host machines. Bind propagation is an advanced topic and many users never need to configure it.

Bind propagation refers to whether or not mounts created within a given bind-mount or named volume can be propagated to replicas of that mount. Consider a mount point /mnt, which is also mounted on /tmp. The propagation settings control whether a mount on /tmp/a would also be available on /mnt/a. Each propagation setting has a recursive counterpoint. In the case of recursion, consider that /tmp/a is also mounted as /foo. The propagation settings control whether /mnt/a and/or /tmp/a would exist.

Propagation setting Description
shared Sub-mounts of the original mount are exposed to replica mounts, and sub-mounts of replica mounts are also propagated to the original mount.
slave similar to a shared mount, but only in one direction. If the original mount exposes a sub-mount, the replica mount can see it. However, if the replica mount exposes a sub-mount, the original mount cannot see it.
private The mount is private. Sub-mounts within it are not exposed to replica mounts, and sub-mounts of replica mounts are not exposed to the original mount.
rshared The same as shared, but the propagation also extends to and from mount points nested within any of the original or replica mount points.
rslave The same as slave, but the propagation also extends to and from mount points nested within any of the original or replica mount points.
rprivate The default. The same as private, meaning that no mount points anywhere within the original or replica mount points propagate in either direction.

Before you can set bind propagation on a mount point, the host filesystem needs to already support bind propagation.

For more information about bind propagation, see the Linux kernel documentation for shared subtree.

The following example mounts the target/ directory into the container twice, and the second mount sets both the ro option and the rslave bind propagation option.

The --mount and -v examples have the same result.

Configure the selinux label