Set image mediatype

Hello everyone!

I was inspecting the manifests of my images after an update and discovered that Docker is now using application/vnd.oci.image.manifest.v1+json as the media type.

I tried searching online but couldn’t find a clear announcement in the official release notes stating when exactly this format became the standard.

According to the list of removed features, the old format was removed in Docker CE cli 28.2

https://github.com/docker/cli/blob/master/docs/deprecated.md#pushing-and-pulling-with-image-manifest-v2-schema-1

But it was deprecated since v19.03

It depends on the image store which media type the manifest uses:

  • if containerd is used: application/vnd.oci.image.manifest.v1+json
  • if dockers own backend is used: application/vnd.docker.distribution.manifest.v2+json

@jmenga shared it with us in this topic: Force Image to Use Manifest Media Type Docker V2, schema 2 Instead of OCI - #12 by jmenga

I ran some tests. I built two images from scratch. One with the containerd image store and one without it. Then I exported and extracted both and checked the json files, because whether the versions are returned when inspecting the image also depends on the image store.

  1. With the containerd image store
cat images1c/index.json | jq
{
  "schemaVersion": 2,
  "mediaType": "application/vnd.oci.image.index.v1+json",
  "manifests": [
    {
      "mediaType": "application/vnd.oci.image.index.v1+json",
      "digest": "sha256:84c4cbf3b9a01570671222e99cb2ccefdb6136f7aa0a50657f322e2102cca090",
      "size": 855,
      "annotations": {
        "io.containerd.image.name": "localhost/test1:latest",
        "org.opencontainers.image.ref.name": "latest"
      }
    }
  ]
}
cat images1c/manifest.json | jq
[
  {
    "Config": "blobs/sha256/80bb5c7e688a677ed9ca2c5bc9a53d8cb190020bcd419597c7eb7b5e5315495d",
    "RepoTags": [
      "localhost/test1:latest"
    ],
    "Layers": [
      "blobs/sha256/670b9c67d25a71b65f4b7c7996899c56c094abce6fe87bcd4cfb1bfcf840b107"
    ]
  }
]
  1. Without the containerd image store
cat images1c/index.json | jq
{
  "schemaVersion": 2,
  "mediaType": "application/vnd.oci.image.index.v1+json",
  "manifests": [
    {
      "mediaType": "application/vnd.oci.image.manifest.v1+json",
      "digest": "sha256:0d0994f611c33b848b82ad252de90fdb7f35f1e7bb5333fb20f2aceb39bcddd8",
      "size": 402,
      "annotations": {
        "io.containerd.image.name": "localhost/test1:latest",
        "org.opencontainers.image.ref.name": "latest"
      }
    }
  ]
}
cat images1/index.json | jq
{
  "schemaVersion": 2,
  "mediaType": "application/vnd.oci.image.index.v1+json",
  "manifests": [
    {
      "mediaType": "application/vnd.oci.image.manifest.v1+json",
      "digest": "sha256:0d0994f611c33b848b82ad252de90fdb7f35f1e7bb5333fb20f2aceb39bcddd8",
      "size": 402,
      "annotations": {
        "io.containerd.image.name": "localhost/test1:latest",
        "org.opencontainers.image.ref.name": "latest"
      }
    }
  ]
}

The only diffrence I noticed is “application/vnd.oci.image.index.v1+json” without containerd and “application/vnd.oci.image.manifest.v1+json” with containerd. Which is strange, because I don’t know why the manifest media type is the same as the index media type when using containerd. It doesn’t seem right, but I may be wrong.

I checked the moby source code. And ran

grep -r 'vnd.docker.distribution.manifest.v2+json' | sort

To get

./api/docs/v1.30.yaml:                MediaType: "application/vnd.docker.distribution.manifest.v2+json"
./api/docs/v1.31.yaml:                MediaType: "application/vnd.docker.distribution.manifest.v2+json"
./api/docs/v1.32.yaml:                MediaType: "application/vnd.docker.distribution.manifest.v2+json"
./api/docs/v1.33.yaml:                MediaType: "application/vnd.docker.distribution.manifest.v2+json"
./api/docs/v1.34.yaml:                MediaType: "application/vnd.docker.distribution.manifest.v2+json"
./api/docs/v1.35.yaml:                MediaType: "application/vnd.docker.distribution.manifest.v2+json"
./api/docs/v1.36.yaml:                MediaType: "application/vnd.docker.distribution.manifest.v2+json"
./api/docs/v1.37.yaml:                MediaType: "application/vnd.docker.distribution.manifest.v2+json"
./api/docs/v1.38.yaml:                MediaType: "application/vnd.docker.distribution.manifest.v2+json"
./api/docs/v1.39.yaml:                MediaType: "application/vnd.docker.distribution.manifest.v2+json"
./api/docs/v1.40.yaml:        example: "application/vnd.docker.distribution.manifest.v2+json"
./api/docs/v1.41.yaml:        example: "application/vnd.docker.distribution.manifest.v2+json"
./api/docs/v1.42.yaml:        example: "application/vnd.docker.distribution.manifest.v2+json"
./api/docs/v1.43.yaml:        example: "application/vnd.docker.distribution.manifest.v2+json"
./api/docs/v1.44.yaml:        example: "application/vnd.docker.distribution.manifest.v2+json"
./api/docs/v1.45.yaml:        example: "application/vnd.docker.distribution.manifest.v2+json"
./api/docs/v1.46.yaml:        example: "application/vnd.docker.distribution.manifest.v2+json"
./api/docs/v1.47.yaml:        example: "application/vnd.docker.distribution.manifest.v2+json"

and

grep -r 'application/vnd.oci.image.manifest.v1+json' | sort

to get

./api/docs/v1.48.yaml:        example: "application/vnd.oci.image.manifest.v1+json"
./api/docs/v1.49.yaml:        example: "application/vnd.oci.image.manifest.v1+json"
./api/docs/v1.50.yaml:        example: "application/vnd.oci.image.manifest.v1+json"
./api/docs/v1.51.yaml:        example: "application/vnd.oci.image.manifest.v1+json"
./api/docs/v1.52.yaml:        example: "application/vnd.oci.image.manifest.v1+json"

What this means exactly I’m not completely sure, but using Docker 28.4, I only see OCI media types.
and ran and according to the version matrix, the API version 1.48 was used in Docker 28.0.

https://docs.docker.com/reference/api/engine/#api-version-matrix

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.