Similar to the question "What´s the sha256 code of a docker image?", I would like to find the digest of a Docker image. I can see the digest when I download an image:
$ docker pull waisbrot/wait:latest
latest: Pulling from waisbrot/wait
Digest: sha256:6f2185daa4ab1711181c30d03f565508e8e978ebd0f263030e7de98deee5f330
Status: Image is up to date for waisbrot/wait:latest
$
Another question, What is the Docker registry v2 API endpoint to get the digest for an image has an answer suggesting the Docker-Content-Digest
header.
I can see that there is a Docker-Content-Digest
header when I fetch the manifest for the image:
$ curl 'https://auth.docker.io/token?service=registry.docker.io&scope=repository:waisbrot/wait:pull' -H "Authorization: Basic ${username_password_base64}"
# store the resulting token in DT
$ curl -v https://registry-1.docker.io/v2/waisbrot/wait/manifests/latest -H "Authorization: Bearer $DT" -XHEAD
* Trying 52.7.141.30...
* Connected to registry-1.docker.io (52.7.141.30) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
* Server certificate: *.docker.io
* Server certificate: RapidSSL SHA256 CA - G3
* Server certificate: GeoTrust Global CA
> GET /v2/waisbrot/wait/manifests/latest HTTP/1.1
> Host: registry-1.docker.io
> User-Agent: curl/7.43.0
> Accept: */*
> Authorization: Bearer LtVRw-etc-etc-etc
>
< HTTP/1.1 200 OK
< Content-Length: 4974
< Content-Type: application/vnd.docker.distribution.manifest.v1+prettyjws
< Docker-Content-Digest: sha256:128c6e3534b842a2eec139999b8ce8aa9a2af9907e2b9269550809d18cd832a3
< Docker-Distribution-Api-Version: registry/2.0
< Etag: "sha256:128c6e3534b842a2eec139999b8ce8aa9a2af9907e2b9269550809d18cd832a3"
< Date: Wed, 07 Sep 2016 16:37:15 GMT
< Strict-Transport-Security: max-age=31536000
However, this header isn't the same. The pull
command got me 6f21
and the header shows 128c
. Further, the pull command doesn't work for that digest:
$ docker pull waisbrot/wait@sha256:128c6e3534b842a2eec139999b8ce8aa9a2af9907e2b9269550809d18cd832a3
Error response from daemon: manifest unknown: manifest unknown
whereas things work as I want when I have the correct digest:
$ docker pull waisbrot/wait@sha256:6f2185daa4ab1711181c30d03f565508e8e978ebd0f263030e7de98deee5f330 12:46 waisbrot@influenza
sha256:6f2185daa4ab1711181c30d03f565508e8e978ebd0f263030e7de98deee5f330: Pulling from waisbrot/wait
Digest: sha256:6f2185daa4ab1711181c30d03f565508e8e978ebd0f263030e7de98deee5f330
Status: Image is up to date for waisbrot/wait@sha256:6f2185daa4ab1711181c30d03f565508e8e978ebd0f263030e7de98deee5f330
What I'm looking for is a way to translate the latest
tag (which changes all the time) into a fixed digest that I can reliably pull. But I don't want to actually pull it down in order to do this translation.
You can pull it by image name and tag. You can replace the tag with a digest. My assumption is that digest is unique per repository so in this case, I am not sure why still the name is required when pulling the image.
The Docker image digest SHA is a critical piece of evidence that makes a container and the content unique. You get the Docker image digest SHA from an image stored in a docker registry. Easy to do if the image has been pulled, just run docker image ls <image> –digests.
When we run any container and the specified Docker image is not present locally then it first pulls it from the registry. Most of the time images are downloaded from a public registry that is 'hub.docker.com' when we create our own custom Docker images as we use the official Docker image as a base image.
For newer versions of Docker, the inspect command provides the correct value:
docker inspect --format='{{index .RepoDigests 0}}' waisbrot/wait
For older versions, fetch the value from the repository following this example with the main Docker repo:
curl -H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
-H "Authorization: Basic ${username_password_base64}" \
'https://auth.docker.io/token?service=registry.docker.io&scope=repository:waisbrot/wait:pull'
Naive attempts to fetch that value fail because the default content-type being selected by the server is application/vnd.docker.distribution.manifest.v1+prettyjws
(a v1 manifest) and you need to v2 manifest. Therefore, you need to set the Accept
header to application/vnd.docker.distribution.manifest.v2+json
.
With 2 http requests, you can get it. The first one to get an authentication token, and the second to get the image digest list by architecture and variant:
token=$(curl --silent "https://auth.docker.io/token?scope=repository:$image:pull&service=registry.docker.io" | jq -r '.token')
curl -s --header "Accept: application/vnd.docker.distribution.manifest.list.v2+json" --header "Authorization: Bearer ${token}" "https://registry-1.docker.io/v2/$image/manifests/$tag" | jq -r '.manifests|.[]| "\(.digest) \(.platform.architecture) \(.platform.variant)"'
Example with:
image=library/nginx
tag=stable-alpine
sha256:8853c7e938c2aa5d9d7439e698f0e700f058df8414a83134a09fcbb68bb0707a amd64 null
sha256:dbcd23f95b94018fe72bfdb356e40f4ae8b95063883f3456fedaed1c02204ed4 arm v6
sha256:d3670edcd50bb07cae303767426adf9bc7ba0219736148d30e6f30dd4e08695c arm v7
sha256:0bcd76faa141e4fa37e875834b3994261e0cfc94b7233ac84896381315b845ca arm64 v8
sha256:da8e62ddb3fab89ff4fa0271dbe230f849ab53402a71338503952437dcda1026 386 null
sha256:269bf99e100294b6b75fbdecf7b4ddbef8b29ea0a953e2e904452a50dbc923ab ppc64le null
sha256:103da50956034c157abeffbc869e2e38a4fabbf913bed8ae6ae7c59e646b28a1 s390x null
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With