diff --git a/docs/reference/commandline/service_create.md b/docs/reference/commandline/service_create.md
index 0f8038401893..1840b767da3b 100644
--- a/docs/reference/commandline/service_create.md
+++ b/docs/reference/commandline/service_create.md
@@ -363,16 +363,34 @@ volumes in a service:
|
The Engine mounts binds and volumes read-write unless readonly option
- is given when mounting the bind or volume.
+ is given when mounting the bind or volume. Note that setting readonly for a
+ bind-mount does not make its submounts readonly on the current Linux implementation. See also bind-nonrecursive.
- true or 1 or no value: Mounts the bind or volume read-only.
- false or 0: Mounts the bind or volume read-write.
|
+
+
+#### Options for Bind Mounts
+
+The following options can only be used for bind mounts (`type=bind`):
+
+
+
+
+ Option |
+ Description |
+
+
+ bind-propagation |
+
+ See the bind propagation section.
+ |
+
consistency |
- |
The consistency requirements for the mount; one of
@@ -384,9 +402,24 @@ volumes in a service:
|
+
+ bind-nonrecursive |
+
+ By default, submounts are recursively bind-mounted as well. However, this behavior can be confusing when a
+ bind mount is configured with readonly option, because submounts are not mounted as read-only.
+ Set bind-nonrecursive to disable recursive bind-mount.
+
+ A value is optional:
+
+
+ - true or 1: Disables recursive bind-mount.
+ - false or 0: Default if you do not provide a value. Enables recursive bind-mount.
+
+ |
+
-#### Bind Propagation
+##### Bind propagation
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
@@ -423,7 +456,7 @@ volumes do not support bind propagation.
For more information about bind propagation, see the
[Linux kernel documentation for shared subtree](https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt).
-#### Options for Named Volumes
+#### Options for named volumes
The following options can only be used for named volumes (`type=volume`):
@@ -459,9 +492,9 @@ The following options can only be used for named volumes (`type=volume`):
the Engine copies those files and directories into the volume, allowing
the host to access them. Set volume-nocopy to disable copying files
from the container's filesystem to the volume and mount the empty volume.
-
- A value is optional:
-
+
+ A value is optional:
+
- true or 1: Default if you do not provide a value. Disables copying.
- false or 0: Enables copying.
diff --git a/man/docker-run.1.md b/man/docker-run.1.md
index 4a1464a74200..5a2218d5bf09 100644
--- a/man/docker-run.1.md
+++ b/man/docker-run.1.md
@@ -453,12 +453,18 @@ according to RFC4862.
* `src`, `source`: mount source spec for `bind` and `volume`. Mandatory for `bind`.
* `dst`, `destination`, `target`: mount destination spec.
- * `ro`, `read-only`: `true` or `false` (default).
+ * `ro`, `readonly`: `true` or `false` (default).
+
+ **Note**: setting `readonly` for a bind mount does not make its submounts
+ read-only on the current Linux implementation. See also `bind-nonrecursive`.
Options specific to `bind`:
* `bind-propagation`: `shared`, `slave`, `private`, `rshared`, `rslave`, or `rprivate`(default). See also `mount(2)`.
* `consistency`: `consistent`(default), `cached`, or `delegated`. Currently, only effective for Docker for Mac.
+ * `bind-nonrecursive`: `true` or `false` (default). If set to `true`,
+ submounts are not recursively bind-mounted. This option is useful for
+ `readonly` bind mount.
Options specific to `volume`:
diff --git a/opts/mount.go b/opts/mount.go
index 8b7082d5dbb0..ef661dd51b75 100644
--- a/opts/mount.go
+++ b/opts/mount.go
@@ -103,6 +103,11 @@ func (m *MountOpt) Set(value string) error {
mount.Consistency = mounttypes.Consistency(strings.ToLower(value))
case "bind-propagation":
bindOptions().Propagation = mounttypes.Propagation(strings.ToLower(value))
+ case "bind-nonrecursive":
+ bindOptions().NonRecursive, err = strconv.ParseBool(value)
+ if err != nil {
+ return fmt.Errorf("invalid value for %s: %s", key, value)
+ }
case "volume-nocopy":
volumeOptions().NoCopy, err = strconv.ParseBool(value)
if err != nil {