Skip to main content

OCI Standard

Open Container Initiative — an open industry standard for container image format and runtime specification maintained by the Linux Foundation. OCI ensures that images built with Docker can run on containerd, podman, CRI-O, and any other OCI-compliant runtime.

OCI Standard — The Open Standard Behind Every Container

What Is the OCI Standard in Simple Terms?

The Open Container Initiative (OCI) is an open standard that defines exactly what a container image is and how it should run. Before OCI, Docker had its own proprietary format. OCI standardised the format so that images built with any tool — Docker, Podman, Buildah, Kaniko — can run on any OCI-compliant runtime — containerd, CRI-O, runc.

TEXT
Before OCI:
Docker image format = Docker-proprietary
Only Docker could build and run Docker images
Vendor lock-in
After OCI:
OCI image format = open standard
Build with: Docker, Podman, Buildah, Kaniko
Run with: containerd, CRI-O, runc, Podman
No vendor lock-in

Two OCI Specifications

Bash
OCI Image Spec:
Defines: what a container image is
Format: layers (tarballs), manifest (JSON), config (JSON)
Every Docker image IS an OCI image
docker build creates OCI-compliant images automatically
OCI Runtime Spec:
Defines: how to run a container from an OCI image
runc: the reference implementation
containerd uses runc internally
Any runtime implementing this spec can run OCI images

Why OCI Matters

Bash
# Build with Docker, run with Podman (no Docker needed)
docker build -t payment-api:latest .
docker save payment-api:latest | podman load
podman run payment-api:latest
# Works because both speak OCI
# Build without Docker (in CI without Docker daemon)
# Kaniko runs inside Kubernetes, builds OCI images
kubectl run kaniko \
--image gcr.io/kaniko-project/executor \
-- --context=git://github.com/org/repo \
--destination registry.razorpay.in/payment-api:latest
# Produces an OCI image that any runtime can execute
# Build with Buildah (rootless, daemonless)
buildah bud -t payment-api:latest .
buildah push registry.razorpay.in/payment-api:latest
# OCI image — works everywhere

OCI and Docker — They Are the Same Format

Bash
# Inspect an image — it is an OCI manifest
docker manifest inspect nginx:1.25
# {
# "schemaVersion": 2,
# "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
# "layers": [
# {"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip", ...}
# ]
# }
# This is an OCI manifest — Docker and OCI specs converged
# Modern Docker images use the OCI format natively
# docker.distribution.manifest.v2 = OCI-compatible

Podman — Docker-Compatible OCI Tool

Bash
# Podman is a Docker-compatible CLI that uses OCI under the hood
# No daemon required (rootless operation)
# Same commands as Docker
podman build -t myapp:latest .
podman run -d myapp:latest
podman push registry.razorpay.in/myapp:latest
# Drop-in replacement in most scripts:
alias docker=podman
# Most Docker commands work identically with Podman
Remember

When you build a Docker image, you are actually creating an OCI image. Docker and the OCI standard are now essentially the same format. This means your images work with any modern container runtime — containerd on Kubernetes, Podman on developer laptops, or any other OCI-compliant tool — with no conversion or modification needed.

Frequently Asked Questions

Why does the OCI standard matter if most people just use Docker?

Before OCI (established by the Linux Foundation around 2015, with Docker as a founding contributor), container image and runtime formats were effectively whatever Docker defined, which locked the ecosystem to one implementation. OCI splits this into an image-spec (how layers and manifests are packaged) and a runtime-spec (how a container is actually executed), so an image built by `docker build` can be pulled and run by containerd, CRI-O, or Podman without modification — this interoperability is exactly what lets Kubernetes swap container runtimes underneath it.

What's a common misconception about Docker images versus OCI images?

People often assume 'Docker image' and 'OCI image' are different things, but modern Docker builds produce OCI-compliant images by default — the Docker-specific image format effectively became a legacy variant once Docker adopted OCI. The practical gotcha is tooling compatibility, not format: some older registries or scanners built against Docker's original manifest format can mishandle newer OCI-specific manifest fields (like multi-arch image indexes) until updated.