diff --git a/docs/reference/commandline/service_create.md b/docs/reference/commandline/service_create.md index 2fd9d6d9d04c..7665f2626ef9 100644 --- a/docs/reference/commandline/service_create.md +++ b/docs/reference/commandline/service_create.md @@ -452,7 +452,24 @@ The following options can only be used for bind mounts (`type=bind`): Read-only mounts are made recursively read-only if kernel is v5.12 or later. Otherwise the Engine raises an error. - When the option is not specified, the default behavior correponds to setting enabled. + When the option is not specified, the default behavior corresponds to setting enabled. + + + + bind-create-host-path + + By default, mounts require the mount point to exist on host. This is a significant difference with + the volumes flag. + Set bind-create-host-path to control the behavior of the engine regarding a non-existent + mount target.
+
+ A value is one of:
+
+ + When the option is not specified, the default behavior corresponds to setting true. diff --git a/opts/mount.go b/opts/mount.go index 0ac252f31187..4538fb84aa1d 100644 --- a/opts/mount.go +++ b/opts/mount.go @@ -131,6 +131,15 @@ func (m *MountOpt) Set(value string) error { default: return fmt.Errorf(`invalid value for %s: %s (must be "enabled", "disabled", "writable", or "readonly")`, key, val) } + case "bind-create-host-path": + switch val { + case "true": + bindOptions().CreateMountpoint = true + case "false": + bindOptions().CreateMountpoint = false + default: + return fmt.Errorf(`invalid value for %s: %s (must be "true" or "false")`, key, val) + } case "volume-subpath": volumeOptions().Subpath = val case "volume-nocopy": diff --git a/opts/mount_test.go b/opts/mount_test.go index 756ad25ca0ed..c4e08afb756d 100644 --- a/opts/mount_test.go +++ b/opts/mount_test.go @@ -325,4 +325,19 @@ func TestMountOptSetBindRecursive(t *testing.T) { }, }, m.Value())) }) + + t.Run("create-host-path", func(t *testing.T) { + var m MountOpt + assert.NilError(t, m.Set("type=bind,source=/foo,target=/bar,bind-create-host-path=true")) + assert.Check(t, is.DeepEqual([]mount.Mount{ + { + Type: mount.TypeBind, + Source: "/foo", + Target: "/bar", + BindOptions: &mount.BindOptions{ + CreateMountpoint: true, + }, + }, + }, m.Value())) + }) }