🧱 "One image. Multiple platforms. Zero surprises."
This is what Docker's multi-platform build and manifest system enables — and it's more relevant than ever in today’s hybrid infrastructure world.
Whether you’re:
- Working on an M1 Mac but deploying to an x86 GKE cluster,
- Building in CI/CD on an ARM-based runner but targeting AMD64 servers,
- Or managing both OpenShift on-prem and GKE on cloud...
You need to build and tag Docker images the right way — to ensure your containers run reliably, regardless of where they're pulled.
In this article, we’ll go brick by brick to explore:
- ✅ What is a multi-platform image build?
- ✅ Why does Docker pull different images on different machines?
- ✅ What exactly is a manifest and why does it matter?
- ✅ How to enforce platform consistency across builds?
- ✅ What breaks if you don’t use platform-aware builds?
And we’ll wrap it all up with:
- 🧠 Real-world DevOps gotchas
- 🛠️ Best practices for Jenkins and CI/CD pipelines
- 📦 Storage and runtime behavior of platform-specific layers
Let’s get started. 🔍
🧱 What is a Docker Multi-Platform Build?
A multi-platform build allows you to create Docker images that can run on multiple CPU architectures (like amd64
, arm64
) from a single machine — even if that machine only supports one architecture.
🧠 Why It Matters
Different environments use different processor types:
- 🖥️ Intel/AMD laptops and servers →
amd64
- 🍏 Apple M1/M2 Macs →
arm64
- 📦 Raspberry Pi →
armhf
,arm64
- ☁️ AWS Graviton or GCP Tau T2A →
arm64
If you don’t build platform-aware images, your container might fail to run on systems it wasn’t built for.
🔍 How Docker Identifies Your Architecture Automatically
When you run:
docker pull busybox
Docker automatically knows your architecture using system calls like:
uname -m # Returns x86_64 or arm64
It uses this info to pull the correct platform image by default — no need for you to explicitly specify the platform unless you're cross-building.
📦 Why SHA256 Digests Differ for Each Platform
Even if the tag is the same (busybox:latest
), the actual SHA256 digest is different for amd64
vs arm64
.
Why?
Each platform compiles binaries differently, so:
- Different binaries = different layers
- Different layers = different image digests
🤔 What Happens If I Pull Two Platform Variants?
Let’s say you do:
docker pull --platform=linux/arm64 busybox
docker tag busybox busybox:arm64
docker pull --platform=linux/amd64 busybox
docker tag busybox busybox:amd64
Now you have two tagged variants.
But if you just do:
docker run busybox
It will run the latest pulled busybox:latest
, which may or may not match your expected platform.
✅ Best Practice:
Explicitly tag and run the desired platform image:
docker run busybox:arm64
docker run busybox:amd64
⚙️ How to Enforce Platform in Docker Build
If you're using a CI/CD pipeline (like Jenkins) or building locally, always fix the platform to avoid surprises:
docker buildx create --use # once per agent
docker buildx build \
--platform=linux/amd64 \
-t myimage:1.0.0 \
--push .
This ensures the image is always built for amd64
, regardless of whether you're on M1, x86, or in the cloud.
📍 Real-World Use Case: Same Image for On-Prem & Cloud
Assume you’re running:
- On-prem OpenShift (OCP) setup
- Target deployment on GCP GKE
Even if both runtime platforms are amd64
, your CI runner may be arm64
(e.g., running on M1 Mac or ARM-based VM). If you don’t specify --platform
, your build may accidentally produce an arm64
image, which won’t work in production.
✅ Solution
In Jenkins or your build script:
docker buildx build \
--platform=linux/amd64 \
-t registry.io/myapp:1.0.0 \
--push .
You can also verify the platform post-build:
docker image inspect myapp:1.0.0 \
--format='{{.Architecture}}/{{.Os}}'
📈 Will Multi-Platform Build Increase Image Size?
Registry Size:
✅ Yes, total size increases because each architecture has its own full image:
-
amd64
: 100MB -
arm64
: 90MB → Registry now stores ~190MB
Local Size:
❌ No, unless you --load
all variants locally (default keeps only the last one).
Runtime Download:
✅ Efficient — Docker pulls only the matching platform image for the host.
📜 Deep Dive into Docker Manifests
🤖 What is a Manifest?
A Docker manifest is a metadata file that maps a Docker image tag to the correct image version for each platform.
Think of it as a:
📦 Smart label that says “if you’re on
amd64
, pull this; ifarm64
, pull that.”
It allows the same tag (myapp:latest
) to point to multiple images, depending on who’s asking.
📖 Real-World Analogy
🍔 A restaurant has one menu item: "Burger".
If an Indian orders, they get a veg burger.
If an American orders, they get a beef burger.
If a Middle Easterner orders, they get a lamb burger.
They all just said “burger” — but they got what’s right for them.
Similarly:
docker pull myapp:latest
returns a platform-specific image — thanks to the manifest.
🔬 What’s Inside a Manifest?
{
"manifests": [
{
"platform": { "architecture": "amd64", "os": "linux" },
"digest": "sha256:aaa..."
},
{
"platform": { "architecture": "arm64", "os": "linux" },
"digest": "sha256:bbb..."
}
]
}
🔍 How to Inspect a Manifest
docker buildx imagetools inspect myapp:latest
✅ What Problems It Solved
Problem | Solved By Manifest |
---|---|
One tag = one platform only | One tag supports many platforms |
Manual selection of image | Automatic matching by Docker |
Broken builds on ARM/M1 | Seamless image pulls |
Multiple tags to manage | Single tag, multi-arch supported |
✅ Final Best Practices Summary
Task | Recommendation |
---|---|
CI builds on mixed-arch runners | Always use --platform in docker buildx build
|
Multi-platform support | Build with --platform=linux/amd64,linux/arm64 and push manifest |
Save registry space | Build only required platforms |
Keep platform control | Tag each variant explicitly (e.g., myapp:arm64 ) |
Validate architecture | Use docker inspect or CI assertions |
🔚 Conclusion
Understanding Docker’s multi-platform builds and manifests is essential in today’s hybrid infrastructure world. Whether you're building locally, on Jenkins, deploying to GKE, or OpenShift — platform consistency matters.
One tag. Many platforms. No surprises.
That's the power of Docker Manifests.
Want to learn how to write your own manifest manually or automate this via Jenkins or GitHub Actions? Comment or connect — happy to help!