Why doesn't my newly-created docker have a digest? - docker

I have been following the Docker tutorial here, and built a test image on my local OSX machine by committing changes to an existing image and tagging it with three different labels:
# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
adamatan/sinatra devel fccb6b4d21b4 8 minutes ago 469.5 MB
adamatan/sinatra junk fccb6b4d21b4 8 minutes ago 469.5 MB
adamatan/sinatra latest fccb6b4d21b4 8 minutes ago 469.5 MB
However, none of these images has a digest:
# docker images --digests adamatan/sinatra
REPOSITORY TAG DIGEST IMAGE ID CREATED SIZE
adamatan/sinatra devel <none> fccb6b4d21b4 9 minutes ago 469.5 MB
adamatan/sinatra junk <none> fccb6b4d21b4 9 minutes ago 469.5 MB
adamatan/sinatra latest <none> fccb6b4d21b4 9 minutes ago 469.5 MB
Other test images I have created with a Dockerfile do have a digest.
Why do some images have a digest and some don't? Is it related to the way the images were created (Dockerfile or not)?

Firstly, Please keep in mind that a digest could represent a manifest, a layer or a combination of them (we normally called that combination an image).
Manifest is a new term that introduced with Docker registry V2. Here is a short description fetched from Docker Registry V2 slides page21 ~ page23:
[Manifest] describes the components of an image in a single object
Layers can be fetched immediately, in parallel.
When you get the digests with command docker images --digests, here the digest is the SHA256 hash of image manifest, but image ID is the hash code of the local image JSON configuration (this configuration is different from manifest). In this case, if an image doesn't have an associated manifest, the digest of that image will be "none".
Normally, two scenarios could make an image doesn't have associated manifest:
This image has not been pushed to or pulled from a V2 registry.
This image has been pulled from a V1 registry.
To generate a manifest, the easiest way is to push the image to a V2 registry (V1 registry will not works). Docker client will generate a manifest locally, then push it with image layers to registry. When you pull the image back, the image will has a manifest.
Once the manifest existing, your image digest should not be "none".

Yes it is related to how the images were created. Docker can be a real stinker at times.
This may be helpful for you in this case.

I was also facing this issue (digest was none).
Reason was when I can the docker image and image was listed in docker images.
At this point, I was checking for the digest value using
docker images --digest
and the digest value comes as <none>.
Resolution:
Push the image in your docker repository, then image will show the digest value.

Related

`docker images --digests` with and without tag give different answers

I am trying to figure out how to determine the digest of an image on my local machine.
If I ask docker images to tell me about the digests for my image, it will happily tell me the correct answer:
rcv#mymachine:~$ docker images -a --digests docker.myregistry.net/myproject/myimage
REPOSITORY TAG DIGEST IMAGE ID CREATED SIZE
docker.myregistry.net/myproject/myimage 8.0.0-rc9 sha256:56993a4bdf42a6337c1e9a32603c8758d9a67b42b525c18c6d500b8688f50c47 2198f19aede7 3 days ago 1.84GB
However, if I try asking specifically about the tag I'm interested in it will tell me that there's no digest.
rcv#mymachine:~$ docker images -a --digests docker.myregistry.net/myproject/myimage:8.0.0-rc9
REPOSITORY TAG DIGEST IMAGE ID CREATED SIZE
docker.myregistry.net/myproject/myimage 8.0.0-rc9 <none> 2198f19aede7 3 days ago 1.84GB
I've been alternating between building this image locally, and just pulling it back down from the registry. Is it possible that docker images is confused, or am I missing some subtle difference between the above two commands?
Thanks!
That appears to be a bug in the docker CLI. This shouldn't have any impact on the underlying digest. If you know the image you want to query, it's probably easier to inspect that image for the digest:
$ docker image inspect nginx:latest --format '{{index .RepoDigests 0}}'
nginx#sha256:644a70516a26004c97d0d85c7fe1d0c3a67ea8ab7ddf4aff193d9f301670cf36

How to generate a Docker digest from a local image

I generated a Docker image locally and once created it appears in docker images --digests but without digest.
REPOSITORY TAG DIGEST IMAGE ID CREATED SIZE
exampleimage local <none> e143f92ce9bc 3 minutes ago 146MB
How can I generate a digest for this image without uploading it to a v2 registry ?
I plan to use it in a subsequent script and upload it only if the script succeed.
Thanks.
Edit: Apparently, the digest does not depend of the registry in v2-2 as found here Why digests are different depend on registry? so it should be possible to generate it locally.

What is docker image reference?

Docker documentation mentions image reference in many places. However, running docker images command gives the list of images with the following properties: REPOSITORY, TAG, IMAGE ID, CREATED, SIZE - no reference. Is 'reference' a synonym for ID or digest, or something else?
The docker image reference is the combination of the REPOSITORY and TAG in this format REPOSITORY:TAG where they are both separated by :. So if you have an image with a REPOSITORY of IMAGE1 and a tag of latest the image reference would be IMAGE1:latest. The knowledge of an image reference would help you to filter by docker image list by reference by running:
docker images --filter=reference='myDocker*:*dev'
The above command will return all docker images that the repository name starts with myDocker and the tag name ends with dev.
To add on to Kelvin's answer, Reference is the Repository which you will use with the tag. Have a look the below example.
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
busybox latest e02e811dd08f 5 weeks ago 1.09 MB
busybox uclibc e02e811dd08f 5 weeks ago 1.09 MB
busybox musl 733eb3059dce 5 weeks ago 1.21 MB
busybox glibc 21c16b6787c6 5 weeks ago 4.19 MB
As you can see above, my reference would be respectively
busybox:latest
busybox:uclibc
busybox:musl
busybox:glibc
If you only use the reference as busybox, by default it will use the latest tag.
You can filter the images on the reference filter as well.
docker images --filter=reference='busy*:*libc'
REPOSITORY TAG IMAGE ID CREATED SIZE
busybox uclibc e02e811dd08f 5 weeks ago 1.09 MB
busybox glibc 21c16b6787c6 5 weeks ago 4.19 MB
You use the image reference in Dockerfile as well when you build the image by using the FROM directive.
FROM busybox #Reference is used as you can see and automatically, `latest` tag will be pulled
...
Ref:- https://docs.docker.com/engine/reference/commandline/images/
Ref:- https://docs.docker.com/engine/reference/builder/#from

What's the difference between a Docker image's Image ID and its Digest?

This has been surprisingly confusing for me. I thought Docker's Image ID is its SHA256 hash. However, apparently the result from docker image ls --digests (listed under the column header DIGEST) is different from the IMAGE ID of that image.
For example
docker image ls --digests alpine
REPOSITORY TAG DIGEST IMAGE ID CREATED SIZE
alpine latest sha256:769fddc7cc2f0a1c35abb2f91432e8beecf83916c421420e6a6da9f8975464b6 055936d39205 2 weeks ago 5.53MB
while
docker image ls --no-trunc
REPOSITORY TAG IMAGE ID CREATED SIZE
...
alpine latest sha256:055936d3920576da37aa9bc460d70c5f212028bda1c08c0879aedf03d7a66ea1 2 weeks ago 5.53MB
Clearly sha256:055936d3920576da37aa9bc460d70c5f212028bda1c08c0879aedf03d7a66ea1 (IMAGE ID) and sha256:769fddc7cc2f0a1c35abb2f91432e8beecf83916c421420e6a6da9f8975464b6 (DIGEST) are not the same value. But why? What's the purpose of having two different sha256 hashes of the same image. How are they calculated, respectively?
I was confused by this when reading the book Docker Deep Dive, and I haven't been able to find a clear answer either in the book or online.
Thanks for michalk's comment. The short answer is:
The "digest" is a hash of the manifest, introduced in Docker registry v2.
The image ID is a hash of the local image JSON configuration.

Docker image's ID and sha256 are this field related and how generated

As stated in title:
There is a relationship between Docker's image ID and image sha256? (If I type docker images --no-trunc I get sha256 as image id)
How image IDs are calculated? It is randomic?
How sha256 is calculated? As far as I know is related with image's content. Am I wrong?
Prior to Docker 1.10 image IDs were random, but since then they are generated deterministically using hashes (SHA256 currently). Each image layer has a digest which is a hash of its contents. The image ID is a different digest, hashed from the configuration - which includes the digests of its layers.
You can see the different digests in the image list and the history:
> docker images --digests
REPOSITORY TAG DIGEST IMAGE ID CREATED
ubuntu latest sha256:28d4c5234db8d5a634d5e621c363d900f8f241240ee0a6a978784c978fe9c737 c73a085dc378 3 days ago
> docker history ubuntu
IMAGE CREATED CREATED BY SIZE COMMENT
c73a085dc378 3 days ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0 B
In the output, the "image ID" is actually the digest of the leaf layer, whereas the image itself has a different digest.
Docker calls this content addressable IDs - the rationale is explained in the Docker 1.10 release notes, and there's a very thorough walkthrough in Nigel Brown's blog post Explaining Docker Image IDs.

Resources