Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I get an image digest without downloading the image?

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.

like image 612
Nathaniel Waisbrot Avatar asked Sep 07 '16 16:09

Nathaniel Waisbrot


People also ask

How do you pull an image with digest value of the image?

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.

How do I get docker digest?

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.

Where do images get pulled from by default when not found locally?

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.


2 Answers

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.

like image 109
Olli Avatar answered Sep 16 '22 15:09

Olli


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
like image 33
jfx Avatar answered Sep 18 '22 15:09

jfx