Pull images used in volumes with type=image#13811
Conversation
glours
left a comment
There was a problem hiding this comment.
The fix proposed will introduce a regression for local images, I think we should reuse the same logic as isServiceImageToBuild
| } | ||
|
|
||
| eg.Go(func() error { | ||
| _, err := s.pullServiceImage(ctx, volService, opts.Quiet, project.Environment["DOCKER_DEFAULT_PLATFORM"]) |
There was a problem hiding this comment.
This unconditionally pulls types.VolumeTypeImage volume sources as external registry images, so docker compose pull --ignore-buildable still tries to pull a volume image that is actually produced by a buildable service in the same project, causing a regression for local/build-only images.
There was a problem hiding this comment.
Thanks for the review @glours. I've updated the PR to use isServiceImageToBuild — volume images produced by buildable services are now skipped when --ignore-buildable is set, and pull failures for buildable images are treated as warnings instead of errors.
When running 'docker compose pull', images referenced in volume mounts with type=image were not being pulled. The pull() function only iterated service images, while pullRequiredImages() (used by 'docker compose up') already handled volume images. This adds the same volume image discovery logic to the pull() function, so that 'docker compose pull' also pulls images used in type=image volume mounts. Volume images that are produced by a buildable service in the project are handled using isServiceImageToBuild: they are skipped when --ignore-buildable is set, and pull failures are treated as warnings (added to mustBuild list) rather than errors. Fixes docker#13809 Signed-off-by: Divyanshu Pandey <pandey.divyanshu03@gmail.com>
80e530d to
39f6e06
Compare
glours
left a comment
There was a problem hiding this comment.
Thanks for working on this. The direction makes sense: docker compose pull should consider images referenced by type: image volumes, especially since up already handles missing volume images through pullRequiredImages.
I think the current implementation needs one more iteration though. It adds separate image-volume discovery directly in pull(), which makes this path diverge from the existing pullRequiredImages, mustPull, and isServiceImageToBuild logic.
That divergence is already visible with deduplication: volume images are queued before service images, so if a service image and a volume image use the same reference, the volume entry wins and the service-level pull logic can be bypassed (pull_policy, buildable image handling, platform, and the --policy flag applied to services).
For a first iteration, I think we should keep the existing service pull policies as the default source of truth when the same image is also used as a volume image. Those policies are explicit, either in the Compose file or through command flags, while image volumes currently don’t have an equivalent place to define pull behavior.
Could you refactor this around a shared helper that collects pull targets for both service images and image-volume sources, reusing the existing mustPull/isServiceImageToBuild semantics where applicable, instead of adding a separate loop in pull()?
Please also add tests for:
- pulling an image used only as a
type: imagevolume; - same image used by a service and a volume, with
pull_policy/--policy; - buildable/local image used as a volume image;
- deduplication between service images and volume images.
Description
When running
docker compose pull, images referenced in volume mounts withtype=imagewere not being pulled. Only the main service images (service.Image)were considered.
The
pullRequiredImages()function (used bydocker compose up) already handledthis case by iterating through service volumes and creating fake
ServiceConfigentries for volume images. However, the
pull()function (used bydocker compose pull)did not have this logic.
This adds the same volume image discovery to the
pull()function so thatdocker compose pullalso pulls images referenced intype=imagevolume mounts.Changes
pkg/compose/pull.go: Added a loop inpull()that iterates each service'svolumes, checks for
type=image, deduplicates againstimagesBeingPulled, andqueues them for pulling via
pullServiceImage().How to test
Fixes #13809