How to Use Container Image Digests to Improve Reproducibility
Tools used in this video
Commands used
docker pull cgr.dev/chainguard/node
docker manifest inspect cgr.dev/chainguard/node@sha256:ede7ef4ca485553f5313f7a02ad3537db1fe337079fc7cfb879f44cf709326db
crane digest --full-ref cgr.dev/chainguard/node
docker pull cgr.dev/chainguard/node:latest@sha256:ede7ef4ca485553f5313f7a02ad3537db1fe337079fc7cfb879f44cf709326db
Dockerfile
FROM cgr.dev/chainguard/go:latest@sha256:7e60584b9ae1eec6ddc6bc72161f4712bcca066d5b1f511d740bcc0f65b05949 AS build
WORKDIR /src
RUN CGO_ENABLED=0 go build -o /bin/server ./src
FROM cgr.dev/chainguard/static AS prod
COPY --from=build /bin/server /bin/
EXPOSE 8000
ENTRYPOINT [ "/bin/server" ]
Transcript
0:05 You might have heard the advice to pin to a digest when using container images.
0:10 But what does this mean?
0:11 Why is it useful and how can you do it?
0:15 So a digest is a content based hash of a unique container image.
0:19 No two container images can have the same digest.
0:23 If you pull an image by the digest, you are guaranteed to get exactly the same image each time.
0:30 And this contrasts with tags like latest or 3.0 which are continually updated and changed.
0:37 So you run pull twice, you might well get a different image.
0:41 And this has implications for reproducibility.
0:46 If images are changing how can I be sure if it works for me it will work for anybody else or myself in the future?
0:52 So what’s the easiest way to get the digest of an image?
0:56 You can run Docker pull and grab it directly from there, for example.
1:02 And you can see the digest right here, but do note that this digest will refer to the index of the image which will list different images for different platforms.
1:15 And most likely this is what you want.
1:18 But we can see what I mean by using the Docker manifest inspect tool.
1:28 And we’ll use this digest and we’ll pipe it through jq.
1:40 And so note that this is the index of the image and it actually lists two more digests that point to actual platform specific images.
1:48 In this case, the arm64 image and the amd64 image.
1:54 If you wanted the image for a specific platform, you could use the address listed here, but not that that might break for some people.
2:02 So make sure you know what you’re doing before using that.
2:06 And I should also mention the crane tool which is a little bit easier to use in scripts as you don’t have to parse the output. If I can spell.
2:16 There we go.
2:18 So here I’ve run crane digest.
2:20 I’ve asked for the full reference which makes it output the beginning part again.
2:24 So we got the digest for the node image as a single line in output.
2:29 And you can also pass a `–platform`` argument which will return the digest for specific platform.
2:38 So I could ask for the arm64 platform and get this digest back.
2:42 OK.
2:43 So now that we have the digest, how can we use it?
2:46 Well, the most obvious way is to just do a Docker pull.
2:53 So here we’ve done a docker pull on node:latest, using this above digest and that works.
3:01 We get back exactly the same image.
3:03 One of the interesting things there and you might have noticed as I went backwards from history is that we can change this tag here.
3:10 It doesn’t, and it turns out Docker or Docker Hub and registries don’t actually care what this tag is when you specify an digest - that part gets ignored.
3:21 So we can put anything at all there and you can use it for metadata.
3:26 But where you’re most likely to use a digest is in the configuration file like a Dockerfile, a compose file or Kubernetes yaml file.
3:35 So I have an example here using the Dockerfile here.
3:39 We’ve pinned the version of the Go compiler.
3:43 And what that means is every time I run the docker build, I’ll be using exactly the same Go compiler.
3:50 So I’m absolutely sure that nothing’s changed in the Go compiler that might cause this build to fail.
3:56 And by using digest in Dockerfiles, we make the whole process much more reproducible; things won’t break because the underlying image has changed in this case.
4:08 And that’s really about it.
4:09 We’ve looked at what our digest is, how you can get it and how you can use it to improve reproducibility.
Last updated: 2023-08-10 15:21