[BUG] Pull=missing always pulls latest image
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
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 I find this happens when I switch projects. So 2 yaml files in different folders with different name but same image.
Can you please try to reproduce with a minimal example, or share your compose files for further analysis ?
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.
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/
Yes the image is present locally, always has been
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.
@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?
@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 thanks for catching this, I'll take look
This issue has been automatically marked as not stale anymore due to the recent activity.