Search code examples
dockerubuntudockerfilemanifestdocker-registry

Modify Docker Image With Older Manifest Format


I am looking for a way to pull a public Ubuntu docker image from dockerhub, modify the (newly changed) manifest format of the image locally, and push the same image with an older manifest format to a private image registry.

This is a temporary need. But we need a stopgap solution for a few months to backport to an older manifest version format until some of our legacy systems can be fully updated to support the new format in all cases -- which is currently preventing pulling down the latest patched Ubuntu base images for 18.04+ images.

As of Feb 2023, the Ubuntu 18.04 and above maintained images switched to the newer manifest format. 16.04 is used as an example below of the old format since it has not been changed.


$ docker manifest inspect ubuntu:16.04

{
   "schemaVersion": 2,
   "mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
   "manifests": [
      {
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         "size": ...,
         "digest": "...",
         "platform": {...}
      },
      {
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         "size": ...,
...

$ docker manifest inspect ubuntu:20.04

{
   "schemaVersion": 2,
   "mediaType": "application/vnd.oci.image.index.v1+json",
   "manifests": [
      {
         "mediaType": "application/vnd.oci.image.manifest.v1+json",
         "size": ...,
         "digest": "...",
         "platform": {...}
      },
      {
         "mediaType": "application/vnd.oci.image.manifest.v1+json",
         "size": ...,
...

TL;DR: How can I:

  • Assuming I have pulled ubuntu:20.04,
  • do something locally to modify/change the image's mediaType from application/vnd.oci.image.index.v1+json (which we do not yet have support for on other places) to the legacy application/vnd.docker.distribution.manifest.list.v2+json format
  • so that we can then push that new (slightly modified manifest) image to our private container registry?

Solution

  • I've been developing a project called regclient that supports modifying images with the regctl image mod command I've added the --to-docker flag that modifies an image like you're asking to do:

    $ regctl manifest get localhost:5000/library/ubuntu:docker
    Name:        localhost:5000/library/ubuntu:docker
    MediaType:   application/vnd.oci.image.index.v1+json
    Digest:      sha256:2adf22367284330af9f832ffefb717c78239f6251d9d0f58de50b86229ed1427
    
    Manifests:
    
      Name:      localhost:5000/library/ubuntu:docker@sha256:b2175cd4cfdd5cdb1740b0e6ec6bbb4ea4892801c0ad5101a81f694152b6c559
      Digest:    sha256:b2175cd4cfdd5cdb1740b0e6ec6bbb4ea4892801c0ad5101a81f694152b6c559
      MediaType: application/vnd.oci.image.manifest.v1+json
      Platform:  linux/amd64
    
    ...
    
    $ regctl image mod localhost:5000/library/ubuntu:docker --to-docker --replace
    localhost:5000/library/ubuntu:docker
    
    $ regctl manifest get localhost:5000/library/ubuntu:docker
    Name:        localhost:5000/library/ubuntu:docker
    MediaType:   application/vnd.docker.distribution.manifest.list.v2+json
    Digest:      sha256:b6d65b608a645e20715adc019ae0a021b7a37d2568ff7e372d29dfade962c30a
    
    Manifests:
    
      Name:      localhost:5000/library/ubuntu:docker@sha256:4933f152eb93fc356968d49da7c3cd42d68eda5e36cfb34ad7d06859c1f132b4
      Digest:    sha256:4933f152eb93fc356968d49da7c3cd42d68eda5e36cfb34ad7d06859c1f132b4
      MediaType: application/vnd.docker.distribution.manifest.v2+json
      Platform:  linux/amd64
    
    ...
    

    The command:

    regctl image mod ${src} --to-docker --replace
    

    modifies an image in place. You can also create a new tag like:

    regctl image mod ${src} --to-docker --create ${new_tag}
    

    Installation instructions are documented in the project. However, since this is a new feature, it will be available in the next (v0.4.8) release, or you can run the edge images now, or download the binaries from the latest CI build.