BuildKit Guide
BuildKit is the next-generation build engine for Docker. It provides significant improvements in performance, storage management, feature set, and security compared to the legacy builder.
What is BuildKit?
BuildKit is a toolkit for converting source code into build artifacts efficiently. It is the default builder in Docker Desktop and Docker Engine 23.0+.
BuildKit vs Legacy Builder
| Feature | Legacy Builder | BuildKit |
|---|---|---|
| Parallel execution | ❌ Sequential only | ✅ Concurrent stages |
| Build cache | Basic layer cache | Advanced cache management |
| Build secrets | ❌ No native support | ✅ --mount=type=secret |
| SSH forwarding | ❌ No native support | ✅ --mount=type=ssh |
| Cache export/import | ❌ No | ✅ Multiple cache backends |
| Multi-platform builds | ❌ No | ✅ Cross-compilation |
| Custom outputs | ❌ Image only | ✅ Image, tar, local, OCI |
| Progress output | Basic | Rich, colored output |
| Build graph optimization | ❌ No | ✅ DAG-based execution |
| Garbage collection | ❌ No | ✅ Automatic |
Enabling BuildKit
Docker Desktop
BuildKit is enabled by default in Docker Desktop. No configuration needed.
Docker Engine (Linux)
# Option 1: Environment variable (per command)
DOCKER_BUILDKIT=1 docker build -t my-app .
# Option 2: Environment variable (session-wide)
export DOCKER_BUILDKIT=1
# Option 3: Daemon configuration (permanent)
# Add to /etc/docker/daemon.json:
{
"features": {
"buildkit": true
}
}
# Restart Docker
sudo systemctl restart docker
# Verify BuildKit is enabled
docker buildx versionBuildKit Architecture
┌──────────────────────────────────────────────────────┐
│ Docker Client │
│ (docker build / buildx) │
└──────────────────────┬───────────────────────────────┘
│ gRPC
▼
┌──────────────────────────────────────────────────────┐
│ BuildKit │
│ │
│ ┌──────────────────────────────────────────────┐ │
│ │ Frontend (LLB) │ │
│ │ Dockerfile → LLB (Low-Level Build) │ │
│ └──────────────────────┬───────────────────────┘ │
│ │ │
│ ┌──────────────────────▼───────────────────────┐ │
│ │ Solver / Scheduler │ │
│ │ Analyzes DAG → Parallel execution plan │ │
│ └──────────────────────┬───────────────────────┘ │
│ │ │
│ ┌────────┐ ┌─────────▼──────┐ ┌──────────────┐ │
│ │ Cache │ │ Workers │ │ Exporters │ │
│ │Manager │ │ (exec, OCI) │ │ (image, tar) │ │
│ └────────┘ └────────────────┘ └──────────────┘ │
└──────────────────────────────────────────────────────┘BuildKit Frontends
The frontend is responsible for parsing the build definition. The default frontend handles Dockerfiles.
Dockerfile Frontend
# syntax=docker/dockerfile:1
# The syntax directive tells BuildKit which frontend to use
# Always use the latest stable version for best features
FROM node:20-alpine
WORKDIR /app
COPY . .
RUN npm ci
CMD ["node", "server.js"]Syntax Versions
| Syntax | Features |
|---|---|
docker/dockerfile:1 | Latest stable features |
docker/dockerfile:1.7 | Specific version |
docker/dockerfile:labs | Experimental features |
BuildKit Mount Types
BuildKit introduces powerful --mount options for RUN instructions:
Cache Mounts
Cache mounts persist data between builds, dramatically speeding up package installations:
# syntax=docker/dockerfile:1
FROM node:20-alpine
WORKDIR /app
COPY package.json package-lock.json ./
# Cache npm packages between builds
RUN --mount=type=cache,target=/root/.npm \
npm ci --only=production
COPY . .
CMD ["node", "server.js"]Cache Mount Examples by Language
# Go modules cache
RUN --mount=type=cache,target=/go/pkg/mod \
--mount=type=cache,target=/root/.cache/go-build \
go build -o /app/server .
# Python pip cache
RUN --mount=type=cache,target=/root/.cache/pip \
pip install -r requirements.txt
# Rust cargo cache
RUN --mount=type=cache,target=/usr/local/cargo/registry \
--mount=type=cache,target=/app/target \
cargo build --release
# Ruby bundler cache
RUN --mount=type=cache,target=/usr/local/bundle/cache \
bundle install
# Maven cache (Java)
RUN --mount=type=cache,target=/root/.m2/repository \
mvn package -DskipTests
# APT package cache
RUN --mount=type=cache,target=/var/cache/apt \
--mount=type=cache,target=/var/lib/apt \
apt-get update && apt-get install -y curlSecret Mounts
Secret mounts make sensitive data available during build without persisting in image layers:
# syntax=docker/dockerfile:1
FROM node:20-alpine
WORKDIR /app
# Secret is available only during this RUN command
RUN --mount=type=secret,id=npmrc,target=/root/.npmrc \
npm ci --only=production
# Secret for cloning private repos
RUN --mount=type=secret,id=github_token \
GITHUB_TOKEN=$(cat /run/secrets/github_token) && \
git clone https://${GITHUB_TOKEN}@github.com/private/repo.git# Pass secrets during build
docker build --secret id=npmrc,src=.npmrc \
--secret id=github_token,src=./github-token.txt \
-t my-app:1.0 .SSH Mounts
SSH mounts forward the SSH agent for secure repository access:
# syntax=docker/dockerfile:1
FROM alpine:3.19
RUN apk add --no-cache git openssh-client
# Clone private repos using SSH agent
RUN --mount=type=ssh \
mkdir -p /root/.ssh && \
ssh-keyscan github.com >> /root/.ssh/known_hosts && \
git clone git@github.com:private/repo.git /app# Build with SSH agent forwarding
eval $(ssh-agent)
ssh-add ~/.ssh/id_rsa
docker build --ssh default -t my-app:1.0 .Bind Mounts
Bind mounts make host files available during build without copying into the image:
# syntax=docker/dockerfile:1
FROM golang:1.22-alpine
WORKDIR /app
# Bind mount go.mod and go.sum for dependency download
RUN --mount=type=bind,source=go.mod,target=go.mod \
--mount=type=bind,source=go.sum,target=go.sum \
go mod download
# Bind mount source for building
RUN --mount=type=bind,target=. \
go build -o /app/server .tmpfs Mounts
tmpfs mounts create temporary filesystems in memory:
# syntax=docker/dockerfile:1
FROM ubuntu:22.04
# Use tmpfs for temporary build data
RUN --mount=type=tmpfs,target=/tmp \
apt-get update && apt-get install -y build-essential && \
make -j$(nproc) -C /src installMount Types Summary
| Mount Type | Purpose | Persists Between Builds | In Final Image |
|---|---|---|---|
cache | Package manager caches | ✅ Yes | ❌ No |
secret | Sensitive data (tokens, keys) | ❌ No | ❌ No |
ssh | SSH agent forwarding | ❌ No | ❌ No |
bind | Host files during build | N/A | ❌ No |
tmpfs | Temporary build data | ❌ No | ❌ No |
Parallel Build Execution
BuildKit analyzes the build graph and executes independent operations in parallel:
# These stages run in parallel
FROM node:20-alpine AS frontend
WORKDIR /frontend
COPY frontend/ .
RUN npm ci && npm run build
FROM golang:1.22-alpine AS backend
WORKDIR /backend
COPY backend/ .
RUN go build -o server .
FROM python:3.12-slim AS ml-model
WORKDIR /ml
COPY ml/ .
RUN pip install -r requirements.txt
# Final stage waits for all parallel stages
FROM alpine:3.19
COPY --from=frontend /frontend/dist /app/public
COPY --from=backend /backend/server /app/server
COPY --from=ml-model /ml/model.pkl /app/model.pkl
CMD ["/app/server"]BuildKit Builders
Builder Drivers
| Driver | Description | Multi-platform | Cache Export |
|---|---|---|---|
docker | Default Docker daemon builder | ❌ | Limited |
docker-container | Runs BuildKit in a container | ✅ | ✅ |
kubernetes | Runs BuildKit in K8s pods | ✅ | ✅ |
remote | Connect to remote BuildKit instance | ✅ | ✅ |
# Create a docker-container builder (recommended for advanced use)
docker buildx create --name mybuilder --driver docker-container --use
# Create a builder with specific configuration
docker buildx create \
--name mybuilder \
--driver docker-container \
--driver-opt network=host \
--buildkitd-flags '--oci-worker-gc-keepstorage 50000' \
--use
# Bootstrap the builder
docker buildx inspect --bootstrap
# List builders
docker buildx ls
# Switch builders
docker buildx use mybuilder
# Remove a builder
docker buildx rm mybuilderGarbage Collection
BuildKit automatically manages its cache with garbage collection:
# /etc/buildkit/buildkitd.toml
[worker.oci]
gc = true
gckeepstorage = 50000 # 50 GB
[[worker.oci.gcpolicy]]
keepBytes = 10737418240 # 10 GB
keepDuration = 604800 # 7 days (in seconds)
filters = ["type==source.local", "type==exec.cachemount", "type==source.git.checkout"]
[[worker.oci.gcpolicy]]
all = true
keepBytes = 53687091200 # 50 GB# Manually prune BuildKit cache
docker buildx prune
# Prune cache older than 24 hours
docker buildx prune --filter "until=24h"
# Prune all cache
docker buildx prune --allNext Steps
- Build Optimization — Optimize build speed and efficiency
- Build Cache — Master cache strategies with BuildKit
- Docker Build Overview — Build fundamentals
- Multi-stage Builds — Advanced multi-stage patterns
- Dockerfile Reference — Complete Dockerfile instruction reference