Wednesday, April 2, 2025

Troubleshooting Docker Image Format: Ensuring Docker v2 Instead of OCI

 

Troubleshooting Docker Image Format: Ensuring Docker v2 Instead of OCI

Introduction

While working with Docker 27+, I encountered an issue where images were being saved in the OCI format instead of the expected Docker v2 schema format. This created compatibility challenges with existing workflows and required a deep dive into Docker's default behaviors, BuildKit, and potential workarounds. In this post, I will walk through the different solutions we explored and how we ultimately resolved the issue.


The Problem: Docker Save Producing OCI Format

When using the docker save command, we expected the output to be in Docker v2 format. However, in our environment, the images were getting stored in OCI format, which was causing issues with certain tools that depended on the legacy Docker format.

We confirmed this by inspecting the saved image:

 tar -tf myimage.tar | head -n 10

If the output contained oci-layout, it indicated that the image was stored in OCI format.


Step 1: Understanding BuildKit’s Role

Starting from Docker 23+, BuildKit is enabled by default. BuildKit improves performance, caching, and parallel execution but also defaults to OCI format unless explicitly configured otherwise.

To check if BuildKit is enabled, we ran:

docker info | grep "BuildKit"

If the output showed BuildKit: true, we knew that the default build system was active and potentially affecting image formats.


Step 2: Disabling BuildKit to Enforce Docker v2 Format

To ensure that Docker saved images in Docker v2 format, we disabled BuildKit using:

DOCKER_BUILDKIT=0 docker save -o myimage.tar my-image:tag

This command forces Docker to use its legacy build system, which saves images in Docker v2 format rather than OCI.


Step 3: Verifying Image Format

After saving the image, we checked the contents again:

tar -tf myimage.tar | head -n 10

If oci-layout was missing and instead we saw manifest.json and layer.tar, it confirmed that the image was now in Docker v2 format.


Step 4: Using Buildx to Ensure Docker Format

If BuildKit had to remain enabled, another approach was using Buildx to explicitly enforce the Docker format:

docker buildx build --output type=docker -t my-image:tag .

Then, saving the image:

docker save -o myimage.tar my-image:tag

This ensured the image was stored using Docker v2 format, even when BuildKit was active.


Step 5: Converting OCI Images to Docker v2 Format

For images that were already saved in OCI format, we used Skopeo to convert them:

skopeo copy oci-archive:myimage.tar docker-archive:myimage-docker.tar

This allowed us to work with the Docker-compatible format without rebuilding the image.


Final Solution and Takeaways

Key Fixes We Found:

Disable BuildKit before saving: DOCKER_BUILDKIT=0 docker save -o myimage.tar my-image:tagUse Buildx to enforce Docker format: docker buildx build --output type=docker -t my-image:tag .Verify saved image format using tar -tf myimage.tarConvert existing OCI images to Docker v2 using skopeo

This process helped us ensure that our Docker images remained in Docker v2 format, avoiding compatibility issues with existing workflows.


Conclusion

Understanding Docker’s default behavior in newer versions and how BuildKit affects image formats was crucial in solving this issue. If you're facing similar problems with Docker images defaulting to OCI format, these solutions should help enforce Docker’s legacy format where needed. 🚀

Feel free to share if you've faced similar challenges and what solutions worked for you!

No comments:

Post a Comment

Troubleshooting Docker Image Format: Ensuring Docker v2 Instead of OCI

  Troubleshooting Docker Image Format: Ensuring Docker v2 Instead of OCI Introduction While working with Docker 27+ , I encountered an iss...