2.2.3.3 OCI Image Portability
A focused guide to OCI Image Portability, connecting core concepts with practical Docker and container operations.
OCI image portability is the practical consequence of the OCI Image Spec: an image built by one tool, on one machine, can be transferred to and run by an entirely different tool, on a different machine, with no compatibility issues, because both sides agree on exactly the same format.
Portability Across Build Tools
An image does not need to be built with Docker specifically to be runnable by Docker; any tool that produces an OCI-compliant image works the same way.
buildah bud -t myapp:1.0 .
buildah push myapp:1.0 registry.example.com/myapp:1.0
docker pull registry.example.com/myapp:1.0
docker run myapp:1.0
This sequence builds an image with one tool entirely, and runs it successfully with another, because both speak the same image format.
Portability Across Registries
Because the distribution of images is also standardized, an image can be pushed to and pulled from any OCI-compliant registry, whether that is Docker Hub, a private registry, or a cloud provider's managed registry service.
docker tag myapp:1.0 registry-a.example.com/myapp:1.0
docker tag myapp:1.0 registry-b.example.com/myapp:1.0
docker push registry-a.example.com/myapp:1.0
docker push registry-b.example.com/myapp:1.0
The same image can be distributed through multiple, entirely unrelated registries without any conversion step.
Portability Across Runtimes
The same image can be run by any OCI-compliant runtime — Docker's engine, containerd directly, or podman — since the runtime's job is to interpret a standard image format, not a format specific to whichever tool happened to build it.
podman run registry.example.com/myapp:1.0
Why Portability Matters in Practice
This portability is what allows a CI pipeline, a developer's laptop, and a production Kubernetes cluster to all use different specific tools while still relying on the exact same image artifact — no step in that chain requires converting between formats, because every tool involved already speaks the same standard.
docker build -t myapp:1.0 .
docker push registry.example.com/myapp:1.0
kubectl set image deployment/myapp myapp=registry.example.com/myapp:1.0
Why This Matters for Avoiding Lock-In
Because the image format itself is not tied to any single vendor's tooling, teams are not locked into a single toolchain for building, storing, or running their container images — any part of that chain can be swapped for an alternative tool without needing to rebuild or reformat existing images.