@@ -39,7 +39,6 @@ import (
3939 "github.com/docker/docker/api/types/blkiodev"
4040 "github.com/docker/docker/api/types/container"
4141 "github.com/docker/docker/api/types/filters"
42- "github.com/docker/docker/api/types/image"
4342 "github.com/docker/docker/api/types/mount"
4443 "github.com/docker/docker/api/types/network"
4544 "github.com/docker/docker/api/types/strslice"
@@ -828,7 +827,6 @@ func getDependentServiceFromMode(mode string) string {
828827 return ""
829828}
830829
831- //nolint:gocyclo
832830func (s * composeService ) buildContainerVolumes (
833831 ctx context.Context ,
834832 p types.Project ,
@@ -838,13 +836,7 @@ func (s *composeService) buildContainerVolumes(
838836 var mounts []mount.Mount
839837 var binds []string
840838
841- img := api .GetImageNameOrDefault (service , p .Name )
842- imgInspect , err := s .apiClient ().ImageInspect (ctx , img )
843- if err != nil {
844- return nil , nil , err
845- }
846-
847- mountOptions , err := buildContainerMountOptions (p , service , imgInspect , inherit )
839+ mountOptions , err := s .buildContainerMountOptions (ctx , p , service , inherit )
848840 if err != nil {
849841 return nil , nil , err
850842 }
@@ -857,11 +849,10 @@ func (s *composeService) buildContainerVolumes(
857849 // see https://github.com/moby/moby/issues/43483
858850 v := findVolumeByTarget (service .Volumes , m .Target )
859851 if v != nil {
860- switch {
861- case v .Type != types .VolumeTypeBind :
852+ if v .Type != types .VolumeTypeBind {
862853 v .Source = m .Source
863- fallthrough
864- case ! requireMountAPI (v .Bind ):
854+ }
855+ if ! bindRequiresMountAPI (v .Bind ) {
865856 source := m .Source
866857 if vol := findVolumeByName (p .Volumes , m .Source ); vol != nil {
867858 source = m .Source
@@ -874,8 +865,8 @@ func (s *composeService) buildContainerVolumes(
874865 v := findVolumeByTarget (service .Volumes , m .Target )
875866 vol := findVolumeByName (p .Volumes , m .Source )
876867 if v != nil && vol != nil {
877- if _ , ok := vol . DriverOpts [ "device" ]; ok && vol . Driver == "local" && vol . DriverOpts [ "o" ] == "bind" {
878- // Looks like a volume, but actually a bind mount which requires the bind API
868+ // Prefer the bind API if no advanced option is used, to preserve backward compatibility
869+ if ! volumeRequiresMountAPI ( v . Volume ) {
879870 binds = append (binds , toBindString (vol .Name , v ))
880871 continue
881872 }
@@ -930,9 +921,9 @@ func findVolumeByTarget(volumes []types.ServiceVolumeConfig, target string) *typ
930921 return nil
931922}
932923
933- // requireMountAPI check if Bind declaration can be implemented by the plain old Bind API or uses any of the advanced
924+ // bindRequiresMountAPI check if Bind declaration can be implemented by the plain old Bind API or uses any of the advanced
934925// options which require use of Mount API
935- func requireMountAPI (bind * types.ServiceVolumeBind ) bool {
926+ func bindRequiresMountAPI (bind * types.ServiceVolumeBind ) bool {
936927 switch {
937928 case bind == nil :
938929 return false
@@ -947,7 +938,24 @@ func requireMountAPI(bind *types.ServiceVolumeBind) bool {
947938 }
948939}
949940
950- func buildContainerMountOptions (p types.Project , s types.ServiceConfig , img image.InspectResponse , inherit * container.Summary ) ([]mount.Mount , error ) {
941+ // volumeRequiresMountAPI check if Volume declaration can be implemented by the plain old Bind API or uses any of the advanced
942+ // options which require use of Mount API
943+ func volumeRequiresMountAPI (vol * types.ServiceVolumeVolume ) bool {
944+ switch {
945+ case vol == nil :
946+ return false
947+ case len (vol .Labels ) > 0 :
948+ return true
949+ case vol .Subpath != "" :
950+ return true
951+ case vol .NoCopy :
952+ return true
953+ default :
954+ return false
955+ }
956+ }
957+
958+ func (s * composeService ) buildContainerMountOptions (ctx context.Context , p types.Project , service types.ServiceConfig , inherit * container.Summary ) ([]mount.Mount , error ) {
951959 mounts := map [string ]mount.Mount {}
952960 if inherit != nil {
953961 for _ , m := range inherit .Mounts {
@@ -959,6 +967,11 @@ func buildContainerMountOptions(p types.Project, s types.ServiceConfig, img imag
959967 src = m .Name
960968 }
961969
970+ img , err := s .apiClient ().ImageInspect (ctx , api .GetImageNameOrDefault (service , p .Name ))
971+ if err != nil {
972+ return nil , err
973+ }
974+
962975 if img .Config != nil {
963976 if _ , ok := img .Config .Volumes [m .Destination ]; ok {
964977 // inherit previous container's anonymous volume
@@ -971,7 +984,7 @@ func buildContainerMountOptions(p types.Project, s types.ServiceConfig, img imag
971984 }
972985 }
973986 volumes := []types.ServiceVolumeConfig {}
974- for _ , v := range s .Volumes {
987+ for _ , v := range service .Volumes {
975988 if v .Target != m .Destination || v .Source != "" {
976989 volumes = append (volumes , v )
977990 continue
@@ -984,11 +997,11 @@ func buildContainerMountOptions(p types.Project, s types.ServiceConfig, img imag
984997 ReadOnly : ! m .RW ,
985998 }
986999 }
987- s .Volumes = volumes
1000+ service .Volumes = volumes
9881001 }
9891002 }
9901003
991- mounts , err := fillBindMounts (p , s , mounts )
1004+ mounts , err := fillBindMounts (p , service , mounts )
9921005 if err != nil {
9931006 return nil , err
9941007 }
0 commit comments