Skip to content

pull: add --dry-run flag to check for newer images without pulling - #7379

Open
raphgm wants to merge 1 commit into
docker:masterfrom
raphgm:pull-dry-run
Open

raphgm wants to merge 1 commit into
docker:masterfrom
raphgm:pull-dry-run

Conversation

@raphgm

@raphgm raphgm commented Oct 13, 2026

Copy link
Copy Markdown
Q A
Is bugfix? ❌
New feature? ✔️
Breaks BC? ❌
Fixed issues #6059

Description

Adds a --dry-run option to docker pull that reports whether pulling an image would download a newer version, without pulling anything.

The CLI asks the daemon to resolve the reference to a digest in the registry (DistributionInspect, i.e. a manifest HEAD lookup) and compares it against the digests recorded on the local image (RepoDigests). Output uses the same Digest: / Status: lines as a regular pull, so existing tooling that parses pull output keeps working:

$ docker pull --dry-run debian
Digest: sha256:3f1d6c17773a45c97bd8f158d665c9709d7b29ed7917ac934086ad96f92e4510
Status: Image is up to date for docker.io/library/debian:latest
docker.io/library/debian:latest

Other statuses:

  • Status: A newer image is available for <ref> — the registry digest differs from the local image's digests.
  • Status: Image <ref> is not available locally and would be pulled — no local image with this reference.

Design notes:

  • --dry-run cannot be combined with --all-tags (digest comparison is per-reference).
  • --quiet suppresses the Digest:/Status: lines, printing only the reference, mirroring regular pull behavior.
  • No daemon changes are required; the check is implemented client-side on top of the existing /distribution/{name}/json endpoint, which already performs the registry HEAD request with the daemon's registry configuration (including insecure registries).
  • The exit code stays 0 as long as the check itself succeeded; the result is communicated through the Status: line.

Docs (markdown + man page) and bash/zsh/fish completions are updated, and unit tests cover the up-to-date, newer-available, not-present-locally, quiet, and invalid-flag-combination cases.

How to verify

$ docker pull --dry-run alpine        # after a fresh pull: "Image is up to date"
$ docker pull --dry-run alpine:3.18   # not local: "would be pulled"

@jmlord

jmlord commented Oct 13, 2026

Copy link
Copy Markdown

Hi, thanks for addressing this! From your description above, I wasn't able to know if there is a way to get a machine-readable result, other than parsing the logs? If not, this would be really useful in scripts.

@raphgm

raphgm commented Oct 13, 2026

Copy link
Copy Markdown
Author

Thanks for taking a look, @jmlord! Good point: at the moment the result is only reported in the Status: line, so a script would have to parse text, which is fragile.

I'll add a --format option for --dry-run, so the result can be consumed directly, for example:

$ docker pull --dry-run --format json alpine
{"Reference":"docker.io/library/alpine:latest","Digest":"sha256:...","Status":"up-to-date"}

$ docker pull --dry-run --format '{{.Status}}' alpine
up-to-date

with Status being one of up-to-date, newer-available or not-present. I'll push an update to this PR shortly.

Add a --dry-run option to "docker pull" that reports whether pulling an
image would download a newer version, without pulling anything.

The CLI asks the daemon to resolve the reference to a digest in the
registry (DistributionInspect) and compares it against the digests of
the local image, printing the same "Digest:" / "Status:" lines as a
regular pull:

    $ docker pull --dry-run debian
    Digest: sha256:3f1d6c...
    Status: Image is up to date for docker.io/library/debian:latest
    docker.io/library/debian:latest

This makes it possible to detect available updates in automation without
downloading the image.

The --dry-run option cannot be combined with --all-tags.

fixes docker#6059

Signed-off-by: Raphael <rdgabmomoh@gmail.com>
@raphgm

raphgm commented Oct 13, 2026

Copy link
Copy Markdown
Author

Pushed an update: docker pull --dry-run --format json <image> (or a Go template such as --format '{{.Status}}') now gives machine-readable output with Reference, Digest and Status (up-to-date, newer-available or not-present). --format can only be used together with --dry-run. Tests, docs, man page and completions are updated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants