Force Image to Use Manifest Media Type Docker V2, schema 2 Instead of OCI

Hi all,

I recently upgraded docker desktop to version 4.31.1 and since then all the images I build have the manifest media type “application/vnd.oci.image.manifest.v1+json”. However, I need them to have the media type “application/vnd.docker.distribution.manifest.v2+json”.

How can I force the images I build to have the manifest media type “application/vnd.docker.distribution.manifest.v2+json”?


OS: Windows 11
Docker Version: 26.1.4 (client), 4.31.1 (server)

Client:
 Version:           26.1.4
 API version:       1.45
 Go version:        go1.21.11
 Git commit:        5650f9b
 Built:             Wed Jun  5 11:29:54 2024
 OS/Arch:           windows/amd64
 Context:           desktop-linux

Server: Docker Desktop 4.31.1 (153621)
 Engine:
  Version:          26.1.4
  API version:      1.45 (minimum version 1.24)
  Go version:       go1.21.11
  Git commit:       de5c9cf
  Built:            Wed Jun  5 11:29:22 2024
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.6.33
  GitCommit:        d2d58213f83a351ca8f528a95fbd145f5654e957
 runc:
  Version:          1.1.12
  GitCommit:        v1.1.12-0-g51d5e94
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

Steps to reproduce:

FROM python:3.11-slim

# Upgrade installed packages
RUN apt-get update && apt-get upgrade -y && apt-get clean

RUN apt-get install -y --no-install-recommends \
      build-essential \
      ca-certificates \
      openjdk-17-jdk-headless \
      && \
    rm -rf /var/lib/apt/lists/*

# Define an entrypoint script for the docker image
ENTRYPOINT ["python"]

# Define command to be passed to the entrypoint
CMD ["-c", "print('Hello, World!')"]
# use local docker registry
docker run -d -p 5000:5000 --name registry registry
docker build -t localhost:5000/example .
docker push localhost:5000/example
# inspect image to see manifest media type
docker buildx imagetools inspect localhost:5000/example
Manifests:
  Name:        localhost:5000/example:latest@sha256:
  MediaType:   application/vnd.oci.image.manifest.v1+json
  Platform:    linux/amd64

What is the result, if you check the metadata of the image after build?

docker manifest inspect localhost:5000/example

If I inspect an image after build, the output looks like this:

{
        "schemaVersion": 2,
        "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
        "config": {
                "mediaType": "application/vnd.docker.container.image.v1+json",
                "size": xxxx,
                "digest": "sha256:randomAlphaNum"
        },
        "layers": [
                {
                        "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
                        "size": xxx,
                        "digest": "sha256:differntAlpaNum"
                },
                ....
        ]
]

Note: this pretty much looks like the example in the docs: https://docs.docker.com/reference/cli/docker/manifest/#examples

Could it be possible that your registry uses an outdated image, which could be responsible for what you see?

Hi, what do you mean by using an outdated image? For the local registry I used the latest version of https://hub.docker.com/_/registry ( docker run -d -p 5000:5000 --name registry registry:latest)(should be 2.8.3).

docker manifest inspect localhost:5000/example

results for me in

no such manifest: localhost:5000/example

Maybe you pulled it long time ago? If the latest tag shares the same sha digest as the 2.8.3. than it is not outdated.

Uhm, but you shared a command that shows you did build the image locally. So it should exist in your local image cache:

The whole point was to determine how the manifest looks like after the build.

Completely understand if this solution is not viable for your use case, but thought I’d chip in anyway.

We had this exact same issue after a recent Docker update. We found the following builder should work:

docker buildx build --platform linux/amd64 --format docker -t BUILD-NAME .

But it didn’t. We weren’t tied to using docker so uninstalled docker and used Podman instead which resulted in the build command:

podman buildx build --platform linux/amd64 --format docker -t BUILD-NAME .

Exactly the same, just swapping docker for podman. Worked first time and got a v2 media type.

Again, sorry if this solution won’t work for you in your specific scenario, just sharing what worked for us on the off chance it’s useful to you.

Happy coding!