Stage 4 · Provision
Production Containers
BuildKit
Use BuildKit for cache mounts, secret mounts, SSH forwarding, parallel builds, and buildx drivers.
What Is BuildKit?
BuildKit is Docker's next-generation build engine. It replaces the legacy builder with parallel execution, better caching, and new features like cache mounts, secret mounts, and SSH forwarding. BuildKit is the default builder in Docker 23.0+.
Enabling BuildKit
# Docker 23.0+ — BuildKit is default
docker build -t myapp .
# Older Docker — enable with environment variable
DOCKER_BUILDKIT=1 docker build -t myapp .
# Verify BuildKit is active (build output shows BuildKit header)
docker build --progress=plain -t myapp . | head -5
# Use buildx for advanced features
docker buildx build -t myapp .BuildKit is enabled by default in recent Docker versions. If you see the old build output format, set DOCKER_BUILDKIT=1 or update Docker.
Cache Mounts
Cache mounts persist package manager caches between builds without including them in image layers. This dramatically speeds up builds that install dependencies. The cache is stored in BuildKit's cache and shared across builds.
# syntax=docker/dockerfile:1
# Node.js — cache npm global modules
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN --mount=type=cache,target=/root/.npm \
npm ci
# Python — cache pip download directory
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN --mount=type=cache,target=/root/.cache/pip \
pip install -r requirements.txt
# Go — cache Go module cache
FROM golang:1.22-alpine
WORKDIR /app
COPY go.mod go.sum ./
RUN --mount=type=cache,target=/go/pkg/mod \
go mod download
# Apt — cache package lists
FROM ubuntu:22.04
RUN --mount=type=cache,target=/var/lib/apt/lists \
--mount=type=cache,target=/var/cache/apt \
apt-get update && apt-get install -y curlCache mounts are not part of the image — they exist only during the build. Package downloads are cached, so subsequent builds skip network fetches. This reduces build time from minutes to seconds.
Always use cache mounts for package managers: npm/pnpm, pip, go mod, apt-get, apk. The cache is per-OS and architecture, so different FROM stages get separate caches.
Secret Mounts
# syntax=docker/dockerfile:1
FROM node:20-alpine
WORKDIR /app
# Mount npm auth token for private packages
RUN --mount=type=secret,id=npmrc,target=/root/.npmrc \
npm ci
# Mount SSH key for private git repos
RUN --mount=type=ssh \
git clone git@github.com:private/repo.git
# Mount AWS credentials
RUN --mount=type=secret,id=aws,target=/root/.aws/credentials \
aws s3 cp s3://bucket/file .Secret mounts are only available during the specific RUN instruction. They are not cached, not stored in layers, and not visible in the final image. The secret is removed after the RUN completes.
SSH Forwarding
# syntax=docker/dockerfile:1
FROM node:20-alpine
WORKDIR /app
# Forward SSH agent to access private repos
RUN --mount=type=ssh \
git clone git@github.com:org/private-lib.git /app/lib
COPY package*.json ./
RUN --mount=type=cache,target=/root/.npm \
npm ciSSH forwarding uses your local SSH agent inside the build. The private key never enters the image. Build with: docker build --ssh default -t myapp .
Parallel Builds
BuildKit builds independent stages in parallel. If your Dockerfile has multiple stages that do not depend on each other, BuildKit executes them simultaneously, significantly reducing build time.
# syntax=docker/dockerfile:1
# These two stages build 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 .
# Final stage depends on both
FROM node:20-alpine
WORKDIR /app
COPY --from=frontend /frontend/dist ./public
COPY --from=backend /backend/server .
CMD ["node", "server.js"]frontend and backend stages build in parallel because neither depends on the other. The final stage waits for both to complete. This can cut build time in half for multi-service images.
BuildKit analyzes the Dockerfile as a directed acyclic graph (DAG). Independent nodes execute in parallel. Dependent nodes wait for their prerequisites. This is fundamentally faster than the legacy builder's sequential execution.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.