Docker manifests describe the layers inside an image. A manifest enables exact comparison of two images, even if they have different tags assigned.
Manifests are expressed in JSON and contain information about the image’s layers and architectures. The Docker client uses manifests to work out whether an image is compatible with the current device. It then uses the information to determine how to start new containers.
The Manifest Format
The manifest schema is currently at version 2. A complete file will declare its schema version and then a list of manifest entries available for the image. Each entry represents a different variant of the image, such as x86 and ARM64.
You can view any image’s manifest using the
docker manifest inspect command. This works with both local images and images stored on a remote registry such as Docker Hub.
docker manifest inspect my-image:latest
The manifest is a list of layers included in the image. You can see the hash of the layer’s content and its overall size.
If you add the
--verbose flag, you’ll get even more information about the image. This includes the image’s tag (in the
Ref field), its architecture, and its operating system.
Docker won’t load manifest details from insecure registries by default. If you need to use an improperly secured registry, add the
--insecure flag to your
docker manifest commands.
Manifests and Multi-Arch Builds
Historically, Docker didn’t support multiple image architectures. Images could only be used on machines with the same architecture as the one they were built on. This quickly proved limiting as Docker found more use in server environments and on newer ARM-based machines.
Besides enabling unique identification of images, manifests facilitate multi-architecture builds. If you inspect an image that supports multiple architectures, you’ll see a subtly different manifest output:
docker manifest inspect php:latest
Running the command above will display the manifest for the official PHP Docker image. You can see from the screenshot that several platform options are available, including AMD64 and ARM. We’ve truncated the full list which actually includes eight different supported architectures.
Manifests let image authors advertise support for multiple architectures under one image tag. The Docker client selects the appropriate image version for its platform, based on the options in the list. It’s expected that authors will only group images that offer identical functionality – there should be no changes beyond the target architecture or operating system.
Each architecture in the list refers to another manifest via its
digest field. The referenced manifest will be a regular single-architecture file. Docker matches the current platform to the right single-arch manifest, then loads that file to determine the final list of image layers.
You can manually create multi-architecture images using the
docker manifest command. Build each of the individual images and push them up to a registry. Then use the
docker manifest create command to combine the images into a new shared manifest under a single tag.
# on an AMD64 machine docker build -t my-image:amd64 . docker push my-image:amd64 # on an ARM machine docker build -t my-image:arm . docker push my-image:arm # now combine the manifests docker manifest create my-image:latest \ --amend my-image:x64 --amend my-image:arm docker manifest push my-image:latest
manifest create with the
--amend flag lets you merge multiple independent manifests together. The final manifest is then pushed to Docker Hub with the
latest tag. AMD64 and ARM users will both be able to create containers from this image.
Manually assembling multi-arch images isn’t mandatory. You can use the
buildx command instead to considerably simplify the process.
docker buildx build --platform linux/amd64,linux/arm64/v8 --tag my-image:latest
This single command results in an image that works on both AMD64 and ARM64 platforms. Under the hood, it’s still producing a multi-arch manifest list, so it’s helpful to understand the inner workings of how images get linked together.
Docker lets you manually override manifest data through annotations. The supported fields include architecture and operating system information.
docker manifest annotate command to setup annotations. If you’re annotating a single-architecture image, supply an image tag that references it. For multi-arch images, you’ll need both the overall image tag and the tag of the individual manifest within the multi-arch manifest list.
docker manifest annotate my-image:latest my-image:amd64 --os-version linux
This command marks the AMD64 version of the
my-image:latest image as a Linux-based container.
Annotations don’t often need to be set by hand. They’re usually inferred automatically from the build environment. You can use the
annotate command to add missing fields or change image configuration in the future.
Docker manifests describe an image’s layers and the architectures it supports. A manifest can be either single architecture, supporting a specific platform, or multi-architecture. In the latter case, the file contains a list of references to the single-arch manifests it incorporates.
Manual interaction with manifests should be rare but is possible with the
docker manifest command group. It’s now more common to automate multi-arch builds via Buildx, which offers a simplified manifest assembly experience.