How to get multi-architecture manifest SHA256 for a Docker image?

PiotrekkrPiotrekkr
3 min read

Sometimes you have to deal with multiple CPU architectures within your team. For example you have devs using macOS (arm64) and Linux (amd64). This may create some issues when you want to use base image with specific SHA256 inside your app Dockerfile. Many base images have support for multiple architectures, for example php:8.3-bookworm image is one of them. It can handle linux/amd64, linux/arm/v7, linux/arm64/v8 and more.

When not using SHA256, docker will pull image specified by tag in architecture that is matching your machine architecture. However with SHA256 specified, it will always use this exact image version and architecture. Here is an example of Dockerfile based on arm64 platform Debian image and what happens when you try to run container.

# syntax=docker/dockerfile:1

# linux/arm64/v8 debian:bookworm version SHA256
FROM debian:bookworm@sha256:b5d17b1bf167551f6780b6fc5c59205a40d16e644087f32e2c604ebb023da5ae
CMD ["echo", "Hello!"]

Building the image throws a warning but image is built.

$ docker build . -t "multiarch:test"  
[+] Building 2.7s (7/7) FINISHED                                                                                                                                                     docker:default
 => [internal] load build definition from Dockerfile                                                                                                                                           0.0s
 => => transferring dockerfile: 226B                                                                                                                                                           0.0s
 => resolve image config for docker-image://docker.io/docker/dockerfile:1                                                                                                                      1.4s
 => docker-image://docker.io/docker/dockerfile:1@sha256:fe40cf4e92cd0c467be2cfc30657a680ae2398318afd50b0c80585784c604f28                                                                       1.0s
 => => resolve docker.io/docker/dockerfile:1@sha256:fe40cf4e92cd0c467be2cfc30657a680ae2398318afd50b0c80585784c604f28                                                                           0.0s
 => => sha256:fd020648a727ee1aa6fe2924bf9c498d19385fa2491ddeecb9da9a499c43e35a 1.26kB / 1.26kB                                                                                                 0.0s
 => => sha256:2ba8a93af1b3f8d1c5354117c15aa2eaa674a24a81b6622506a8a524ba8d3fc9 12.46MB / 12.46MB                                                                                               0.6s
 => => sha256:fe40cf4e92cd0c467be2cfc30657a680ae2398318afd50b0c80585784c604f28 8.40kB / 8.40kB                                                                                                 0.0s
 => => sha256:dc9e236567481e0aca4c1f52351af213b9a176622f10e3f4a86e5cc48919fa01 482B / 482B                                                                                                     0.0s
 => => extracting sha256:2ba8a93af1b3f8d1c5354117c15aa2eaa674a24a81b6622506a8a524ba8d3fc9                                                                                                      0.3s
 => [internal] load metadata for docker.io/library/debian:bookworm@sha256:b5d17b1bf167551f6780b6fc5c59205a40d16e644087f32e2c604ebb023da5ae                                                     0.0s
 => [internal] load .dockerignore                                                                                                                                                              0.0s
 => => transferring context: 2B                                                                                                                                                                0.0s
 => CACHED [1/1] FROM docker.io/library/debian:bookworm@sha256:b5d17b1bf167551f6780b6fc5c59205a40d16e644087f32e2c604ebb023da5ae                                                                0.0s
 => exporting to image                                                                                                                                                                         0.0s
 => => exporting layers                                                                                                                                                                        0.0s
 => => writing image sha256:cb215f3f2aa61956965f685915da7f9cc8f54d3d7fd80ac90c724e9e46bcce89                                                                                                   0.0s
 => => naming to docker.io/library/multiarch:test                                                                                                                                              0.0s

 1 warning found (use --debug to expand):
 - InvalidBaseImagePlatform: Base image debian:bookworm@sha256:b5d17b1bf167551f6780b6fc5c59205a40d16e644087f32e2c604ebb023da5ae was pulled with platform "linux/arm64", expected "linux/amd64" for current build (line 4)

Running container using this image on linux/amd64 does not work and throws warning and error.

$ docker run -it --rm multiarch:test
WARNING: The requested image's platform (linux/arm64/v8) does not match the detected host platform (linux/amd64/v3) and no specific platform was requested
exec /usr/bin/echo: exec format error

To be able to work with SHA256 you should use image manifest list SHA256 instead of platform specific SHA256. This will allow docker to pull this specific manifest list, look inside, and then select correct image version from a list of platform specific images.

The issue with obtaining manifest list SHA256 is that it is not easily available when you inspect docker image on your machine. This is because docker pulls only image suited for your machine architecture and docker inspect show info about this version.

So, what is a quick and easy way to get to know manifest list SHA256? Use docker buildx imagetools like this:

docker buildx imagetools inspect <image-tag>

For example with php:8.3-bookworm it shows this:

docker buildx imagetools inspect php:8.3-bookworm 
Name:      docker.io/library/php:8.3-bookworm
MediaType: application/vnd.docker.distribution.manifest.list.v2+json
Digest:    sha256:d5338bd62184c4ae4526b9e7a93de80acc5436e31d262f3063a4ad5ed4b1308a

Manifests: 
  Name:      docker.io/library/php:8.3-bookworm@sha256:fa9d0d6d4def5fb95c76df2378589a76f3056728bab022035969cfe19f55b7f8
  MediaType: application/vnd.docker.distribution.manifest.v2+json
  Platform:  linux/amd64

  Name:      docker.io/library/php:8.3-bookworm@sha256:c504fdab2c2eb401e75725e305809fa784a234e2154932c77cad1d65916232ab
  MediaType: application/vnd.docker.distribution.manifest.v2+json
  Platform:  linux/arm/v5

  Name:      docker.io/library/php:8.3-bookworm@sha256:7c4426644bb16392e39337b17fa3fc94fa9f83963aba0c0e770053a79c533e49
  MediaType: application/vnd.docker.distribution.manifest.v2+json
  Platform:  linux/arm/v7

  Name:      docker.io/library/php:8.3-bookworm@sha256:ca695b750ec6c2e35d7bf2e179214d550af54513ed6938ed451bfc47923a5883
  MediaType: application/vnd.docker.distribution.manifest.v2+json
  Platform:  linux/arm64/v8

  Name:      docker.io/library/php:8.3-bookworm@sha256:5e3007483eceb423cec0743b244a5fec17d7d29734edb979d69502916833ec7a
  MediaType: application/vnd.docker.distribution.manifest.v2+json
  Platform:  linux/386

  Name:      docker.io/library/php:8.3-bookworm@sha256:665198ade296ce6aef6673e3ab20b89c8929e4fa113e827376a95f5ca01ea41d
  MediaType: application/vnd.docker.distribution.manifest.v2+json
  Platform:  linux/mips64le

  Name:      docker.io/library/php:8.3-bookworm@sha256:462c12dbddf39cd8ac505ad8c843da0f67ca9e5df78953de497e26787a296734
  MediaType: application/vnd.docker.distribution.manifest.v2+json
  Platform:  linux/ppc64le

  Name:      docker.io/library/php:8.3-bookworm@sha256:0658067171ca406a755c11f514415253593ae0ec450d058740d3b2ece8c034e7
  MediaType: application/vnd.docker.distribution.manifest.v2+json
  Platform:  linux/s390x

First digest from the top is a multi-architecture manifest list SHA256 that can be used as a base for builds. Remaining digests are platform specific ones and docker will pull those images when you want to use them on matching machine architecture.

0
Subscribe to my newsletter

Read articles from Piotrekkr directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Piotrekkr
Piotrekkr