BuildKit and Buildx
BuildKit is Docker’s modern build backend. It improves build speed, cache behavior, Dockerfile features, and multi-platform output. Docker Engine uses BuildKit by default in current releases, and docker buildx is the CLI front end for advanced builds.
Check the local builder first.
1docker buildx version
2docker buildx ls
The default builder is enough for many local builds. For multi-platform builds, shared registry cache, or isolated CI builders, create a named builder that uses the docker-container driver.
1docker buildx create --name book-builder --driver docker-container --use
2docker buildx inspect --bootstrap
Dockerfile syntax
Start Dockerfiles that use newer BuildKit features with the syntax directive.
1# syntax=docker/dockerfile:1
2FROM python:3-slim
The directive lets Docker use the current stable Dockerfile frontend even when the builder host is not upgraded at the same pace as the project.
Cache mounts
Cache mounts keep dependency caches outside the final image while still reusing them across builds. This pattern is useful for package managers such as pip, npm, apt, maven and gradle.
1# syntax=docker/dockerfile:1
2FROM python:3-slim
3
4WORKDIR /app
5COPY requirements.txt .
6RUN --mount=type=cache,target=/root/.cache/pip \
7 pip install --no-cache-dir -r requirements.txt
8
9COPY . .
10CMD ["python", "app.py"]
The cache directory is available while the RUN instruction executes. It is not copied into the image layer.
Build secrets
Do not pass tokens through ARG or ENV. They can leak through image history or build logs. Use BuildKit secrets so credentials are mounted only for the instruction that needs them.
1export PIP_TOKEN="..."
2docker buildx build \
3 --secret id=pip_token,env=PIP_TOKEN \
4 -t example/app:dev .
The Dockerfile reads the secret from the temporary mount.
1# syntax=docker/dockerfile:1
2RUN --mount=type=secret,id=pip_token \
3 PIP_TOKEN="$(cat /run/secrets/pip_token)" && \
4 pip config set global.extra-index-url "https://token:${PIP_TOKEN}@packages.example.com/simple"
Registry cache
CI runners are often ephemeral. Registry-backed cache lets each new runner reuse layers from previous builds.
1docker buildx build \
2 --cache-from type=registry,ref=registry.example.com/team/app:buildcache \
3 --cache-to type=registry,ref=registry.example.com/team/app:buildcache,mode=max \
4 -t registry.example.com/team/app:${GIT_SHA} \
5 --push .
Use a separate cache tag so application tags and build-cache metadata have different lifecycles.
Build output
Buildx can load an image into the local Docker image store, push it to a registry, or write files to disk.
1# Local single-platform development image
2docker buildx build --load -t example/app:dev .
3
4# Registry image for deployment
5docker buildx build --platform linux/amd64 -t registry.example.com/team/app:prod --push .
Keep ordinary docker build for quick local work when it is enough. Move to docker buildx build when the build needs cache export, secrets, attestations, or multi-platform output.