
Table of Contents
By Khimananda Oli | Last reviewed: August 2026
Slow container builds and fragile CI pipelines remain primary bottlenecks for teams shipping software at scale. Docker BuildKit and buildx solve this by replacing the legacy sequential builder with a concurrent, graph-based execution engine that supports multi-platform targeting, advanced caching, and secure secret handling natively. If you are still running plain docker build commands in 2026, you are leaving significant performance and security gains on the table.
How does Docker BuildKit and buildx improve build performance?
The fundamental difference between the legacy Docker builder and Docker BuildKit and buildx lies in how they interpret and execute your Dockerfile. The old builder processed instructions sequentially, rebuilding entire layers whenever a cache miss occurred, even if subsequent steps were independent. BuildKit treats your Dockerfile as a dependency graph (LLB - Low-Level Build), allowing it to identify and execute independent stages concurrently.
In practice, this means if your Dockerfile has separate stages for compiling Go binaries and building frontend assets, BuildKit runs them simultaneously rather than waiting for one to finish before starting the other. For complex microservices or monorepos, this alone can cut build times by 30–50%. Beyond parallelism, BuildKit introduces intelligent cache invalidation. It tracks content hashes rather than just timestamps, so copying a README into your context won't invalidate your npm install layer—a common frustration with the legacy builder.
To leverage these improvements locally after you install Docker on Ubuntu, ensure BuildKit is enabled. In modern Docker Desktop and Engine versions (23.0+), it is the default. You can verify or force it via environment variable:
<!-- Enable BuildKit explicitly -->
export DOCKER_BUILDKIT=1
<!-- Or configure permanently in /etc/docker/daemon.json -->
{
"features": {
"buildkit": true
}
} How do you configure multi-platform builds with Docker buildx?
Multi-platform support is the killer feature of Docker BuildKit and buildx. With Apple Silicon Macs, ARM-based cloud instances (AWS Graviton, Azure Cobalt), and edge devices all gaining traction, shipping single-architecture images is no longer acceptable. The buildx CLI wraps BuildKit to make cross-compilation manageable through QEMU emulation or native remote builders.
Setting up a multi-platform builder instance
You cannot use the default Docker driver for multi-platform builds. Create a dedicated builder instance with the docker-container driver, which runs BuildKit inside a privileged container:
# Create and bootstrap a new builder
docker buildx create --name multiarch --driver docker-container --bootstrap
# Verify supported platforms
docker buildx inspect multiarch --bootstrap
# Set as default (optional)
docker buildx use multiarch --default Building and pushing multi-arch images
When targeting multiple architectures, you must push directly to a registry. Multi-platform manifests cannot be stored in the local Docker image store. Use the --platform flag with comma-separated targets:
docker buildx build \
--platform linux/amd64,linux/arm64,linux/arm/v7 \
--tag registry.example.com/myapp:v1.2.0 \
--push \
. A common mistake is attempting to test multi-platform images locally without specifying the platform. Always validate the specific architecture you need using docker run --platform linux/arm64 ... to avoid false positives from automatic emulation masking issues.
What are the best caching strategies for Docker BuildKit in CI?
Caching is where Docker BuildKit and buildx delivers its highest ROI in continuous integration environments. Unlike the legacy builder which relies solely on local layer caches (often lost between ephemeral CI runners), BuildKit supports external cache backends. This persistence across pipeline runs prevents redundant work like reinstalling dependencies or recompiling unchanged modules.
- Inline Cache: Embeds cache metadata directly into the final image. Best for simple projects where image size overhead (~5-10%) is acceptable. Enables any pull to serve as a cache source.
- Registry Cache: Stores cache layers separately in a registry tag. Ideal for large monorepos or heavy compilation tasks. Keeps production images lean while maintaining fast rebuilds.
- Local/Volume Cache: Persists cache on disk or named volumes. Perfect for self-hosted runners or local development where network latency to a registry is undesirable.
- GHA/S3/Azure Cache: Native integrations with GitHub Actions, AWS S3, or Azure Blob Storage. Eliminates registry overhead entirely for cloud-native CI pipelines.
For most teams using GitHub Actions, the GHA cache backend offers the best balance of speed and cost. Here is a production-ready configuration:
docker buildx build \
--cache-from type=gha \
--cache-to type=gha,mode=max \
--tag myapp:${{ github.sha }} \
--push \
. The mode=max parameter is critical—it exports cache for all intermediate layers, not just the final stage. Without it, expensive compilation steps in early stages may still re-run. For self-hosted runners on persistent infrastructure, consider combining volume mounts with registry fallback as described in our guide to speeding up CI builds with caching.
How do you manage secrets securely during Docker builds?
Secret management during builds has historically been a major security gap. Developers would copy .env files or embed API keys in layers, leaving credentials exposed in image history even after deletion. Docker BuildKit and buildx solves this with mounted secrets and SSH agents that never persist to disk or image layers.
Using BuildKit secret mounts
Secrets are passed at build time via the --secret flag and accessed through a temporary mount. They exist only in memory during the specific RUN instruction:
# syntax=docker/dockerfile:1
FROM node:20-alpine AS builder
WORKDIR /app
# Mount secret as file, never written to layer
RUN --mount=type=secret,id=npm_token,target=/root/.npmrc \
npm ci --production
COPY . .
RUN npm run build Invoke the build with the secret sourced from environment variables or files:
# From environment variable
NPM_TOKEN=$(cat ~/.npmrc) docker buildx build \
--secret id=npm_token,env=NPM_TOKEN \
--tag myapp:secure \
.
# From file directly
docker buildx build \
--secret id=npm_token,src=.npmrc \
--tag myapp:secure \
. SSH agent forwarding
For private Git repositories or SSH-authenticated package registries, forward your SSH agent instead of copying keys:
RUN --mount=type=ssh \
git clone [email protected]:private-org/internal-lib.git This pattern ensures private keys never leave your host machine. Combined with SBOM generation and signing practices covered in our DevSecOps shift-left guide, this creates an audit-ready build pipeline suitable for SOC 2 and ISO 27001 compliance frameworks.
| Feature | Legacy Builder | Docker BuildKit & buildx |
|---|---|---|
| Execution Model | Sequential, line-by-line | Parallel DAG (LLB) |
| Multi-Platform | Not supported | Native via QEMU/remote |
| Cache Backends | Local layers only | Registry, GHA, S3, Local, Inline |
| Secret Handling | ARG/COPY (leaked in history) | Mounted secrets (never persisted) |
| Build Output | Local image only | Registry, OCI layout, tar, local |
| Skip Unused Stages | No (executes all) | Yes (only required nodes) |
Adopt Docker BuildKit and buildx for Production Workflows
Migrating to Docker BuildKit and buildx is no longer optional for teams serious about velocity, security, and multi-architecture support. The transition requires updating CI configurations and potentially restructuring Dockerfiles to maximize parallelism, but the payoff in reduced pipeline duration and hardened supply chains is immediate. Start by enabling BuildKit locally, then progressively roll out multi-platform builders and external caching in your CI environment. Audit your current build times and secret handling practices—if either falls short, this toolchain is your remediation path.
Need help architecting a compliant, high-performance container build pipeline? Contact me to discuss your infrastructure requirements or explore our deep dive on multi-platform builds for advanced patterns.