compose icon indicating copy to clipboard operation
compose copied to clipboard

[BUG] Pull=missing always pulls latest image

Open fire015 opened this issue 8 months ago • 6 comments

Description

Whenever I run:

docker compose up -d --pull=missing

It will try to pull the latest image despite phpmyadmin:latest already downloaded.

I have specified in my compose yaml file: image: phpmyadmin

Is this the intended behavior? Image is not missing so the pull flag is confusing....

Mac / Docker Desktop 4.40.0 (187762) / Engine: 28.0.4 / Compose: v2.34.0-desktop.1

Steps To Reproduce

No response

Compose Version

v2.34.0-desktop.1

Docker Environment


Anything else?

No response

fire015 avatar Apr 09 '25 09:04 fire015

I can't reproduce. After initial pull, --pull=missing (which is the default value) doesn't trigger image pull

Please check docker image inspect phpmyadmin

ndeloof avatar Apr 09 '25 14:04 ndeloof

@ndeloof I find this happens when I switch projects. So 2 yaml files in different folders with different name but same image.

fire015 avatar Apr 10 '25 07:04 fire015

Can you please try to reproduce with a minimal example, or share your compose files for further analysis ?

ndeloof avatar Apr 10 '25 08:04 ndeloof

Theres definitely some sort of time cache behind this, if I re-run the up and down command across different projects it won't pull after the first time. But after maybe 24 hours it will try and pull.

name: project1

services:
  db:
    image: mysql:8.0
    ports:
      - 3306:3306
    volumes:
      - mysql:/var/lib/mysql

  phpmyadmin:
    image: phpmyadmin
    environment:
      - PMA_HOST=db
    ports:
      - 8080:80

volumes:
  mysql:

$ docker compose up -d --pull=missing [+] Running 2/2 ✔ db Pulled 2.9s ✔ phpmyadmin Pulled

$ docker compose down -t 0 [+] Running 3/3 ✔ Container project1-phpmyadmin-1 Removed 0.2s ✔ Container project1-db-1 Removed

Up again will not pull, but if you try this 24 hours later it will.

fire015 avatar Apr 11 '25 08:04 fire015

Before doing a docker compose up -d -pull=missing can you check if the image is present locally with docker images?

If this is not the case and you don't have any specific policy to remove images after a certain amount of time, can you please open an issue in https://github.com/docker/for-mac/

glours avatar Apr 14 '25 08:04 glours

Yes the image is present locally, always has been

fire015 avatar Apr 16 '25 18:04 fire015

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

github-actions[bot] avatar Sep 14 '25 00:09 github-actions[bot]

@glours @ndeloof I also ran across this issue (on linux, so it seems not macOS-specific).

I have compose files with multiple services defined and some are always pulled, despite the image being up to date locally.

I noticed, this does only happen for images/tags which are a bit older like 3 or 6 months. Newer images don't seem have this issue.

Sadly I am unable to provide you something reproducable since the images are stored locally in my private container registry.

I was not able to reproduce this with older images from public sources (eg. docker hub).

Are there any timing or age based checks involved whether to pull an image or not?

ston1th avatar Oct 20 '25 14:10 ston1th

@glours @ndeloof Digging a bit further, I found a reproducable version.

Command: docker compose pull --policy=missing

This happens every time a digest is used in the image spec:

services:
  alpine:
    image: alpine:3.22.2@sha256:4b7ce07002c69e8f3d704a9c5d6fd3053be500b7f1c69fc0d80990c2ad8dd412

or

services:
  alpine:
    image: alpine@sha256:4b7ce07002c69e8f3d704a9c5d6fd3053be500b7f1c69fc0d80990c2ad8dd412

When is use this, the second image pull is skipped as expected:

services:
  alpine:
    image: alpine:3.22.2

I tracked it this to this function (imageAlreadyPresent): https://github.com/docker/compose/blob/e25265dd55db8f6fc2d6ed7cbb3f45ac565354c5/pkg/compose/pull.go#L157

It calls ParseDockerRef over here. https://github.com/distribution/reference/blob/727f80d42224f6696b8e1ad16b06aadf2c6b833b/normalize.go#L127

ParseDockerRef only returns a TagNameOnly when there is no digest in the image. Since there is a digest, the interface conversion in imageAlreadyPresent over here always fails and false is returned even the image exists locally: https://github.com/docker/compose/blob/e25265dd55db8f6fc2d6ed7cbb3f45ac565354c5/pkg/compose/pull.go#L162-L165

ston1th avatar Oct 20 '25 15:10 ston1th

@ston1th thanks for catching this, I'll take look

glours avatar Oct 20 '25 15:10 glours

This issue has been automatically marked as not stale anymore due to the recent activity.

stale[bot] avatar Oct 20 '25 15:10 stale[bot]