moby: Digest is lost after loading a saved image

Output of docker version:

Client:
 Version:      1.10.3
 API version:  1.22
 Go version:   go1.5.3
 Git commit:   20f81dd
 Built:        Thu Mar 10 15:59:07 2016
 OS/Arch:      linux/amd64

Server:
 Version:      1.10.3
 API version:  1.22
 Go version:   go1.5.3
 Git commit:   20f81dd
 Built:        Thu Mar 10 15:59:07 2016
 OS/Arch:      linux/amd64

Output of docker info:

Containers: 0
 Running: 0
 Paused: 0
 Stopped: 0
Images: 1
Server Version: 1.10.3
Storage Driver: aufs
 Root Dir: /var/lib/docker/aufs
 Backing Filesystem: extfs
 Dirs: 1
 Dirperm1 Supported: true
Execution Driver: native-0.2
Logging Driver: json-file
Plugins: 
 Volume: local
 Network: bridge null host
Kernel Version: 4.2.0-25-generic
Operating System: Ubuntu 15.10
OSType: linux
Architecture: x86_64
CPUs: 8
Total Memory: 31.06 GiB
Name: liron-srv
ID: 32RZ:CFUB:DHXV:UVCO:CALO:XNZE:7CAJ:YDSR:AHZB:A2QK:46R6:3525
Username: twistlockreader
Registry: https://index.docker.io/v1/

Additional environment details (AWS, VirtualBox, physical, etc.): physical

Steps to reproduce the issue:

  1. pull with digest docker pull "alpine@sha256:4f2d8bbad359e3e6f23c0498e009aaa3e2f31996cbea7269b78f92ee43647811"
  2. image has digest docker images --digests
  3. Save image docker save alpine@sha256:4f2d8bbad359e3e6f23c0498e009aaa3e2f31996cbea7269b78f92ee43647811 > test.tar
  4. Delete the image docker rmi alpine@sha256:4f2d8bbad359e3e6f23c0498e009aaa3e2f31996cbea7269b78f92ee43647811
  5. Load the new image docker load < test.tar
  6. image has no digest docker images --digests also in docker inspect. Describe the results you received: Digest disappear (and RepoTags and RepoDigests are empty).

Describe the results you expected: Repo tags and digests remain the same Additional information you deem important (e.g. issue happens only occasionally):

About this issue

  • Original URL
  • State: open
  • Created 8 years ago
  • Comments: 18 (13 by maintainers)

Commits related to this issue

Most upvoted comments

Thanks for the clarification @aaronlehmann, few follow ups:

  1. Any reason not include the RepoDigests field in regular pulls?
  2. Image ID is not persistent across machines, so I’m not sure how it is usable to verify trust (especially since trust is established via the digest)
  3. Why not include the original manifest as part of the image specification?

Just stumbled across the same problem. We have to use docker save/load to distribute Docker images as we don’t have access to the internet on the destination hosts. We also have to make sure that the images on the destination hosts end up being exactly the same that were used while bundling the application. Content addressable images sounded perfect for this, but due to this issue this does not work as we hoped.

The digest field is only populated for images that are pulled by digest. So loading an image from a tar won’t fill it.

I’m not sure the field could be carried through on save/load because of the security implications. A saved image could lie about the manifest’s digest, since the manifest is not part of the saved image.

Generally, it’s better to use use the image ID to check image provenance. The image ID is a secure hash over the image itself, whereas the RepoDigests is a hash over the manifest received from the registry.

This is no longer blocking us, because we’ve found a workaround, but it’s a bit of a hack:

  • When we build the installer, we search all our compose files, looking for images which specify a digest (e.g. foo@sha256:bar)
  • We pull the required image using the specified image
  • We generate a unique tag from the digest (e.g. sha256:bar -> digest_sha256_bar)
  • The digest-specified image is retagged with the new tag (e.g. docker tag 'foo@sha256:bar' 'foo:digest_sha256_bar')
  • The image in included in the images bundle using this new tag
  • The copy of the compose file in the installer is edited to use the tag instead of the digest