These features cut CI build times dramatically and are the right way to use secrets during builds.
BuildKit is Docker's build engine (the default since Engine 23; docker build is an alias for docker buildx build). Beyond parallel stages and skipping unused ones, it adds Dockerfile features. Start the file with # syntax=docker/dockerfile:1 to get the latest stable syntax.
Cache mounts persist a directory across builds without putting it in the image:
RUN --mount=type=cache,target=/root/.cache/pip pip install -r requirements.txtEven when the layer's cache is invalidated, pip, npm, Go or apt find their download caches warm, so reinstalls take seconds.
Secret mounts expose a secret file to a single RUN without writing it into any layer or the build history:
RUN --mount=type=secret,id=npmrc,target=/root/.npmrc npm ciand build with docker build --secret id=npmrc,src=$HOME/.npmrc ..
SSH mounts (RUN --mount=type=ssh git clone git@github.com:acme/private.git with docker build --ssh default .) forward your SSH agent for private dependencies, with no keys copied.
Bind mounts (--mount=type=bind,source=.,target=/src) read files from the context without a COPY layer, useful when only build output is needed.
Heredocs let you write multi-line scripts inline: RUN <<EOF ... EOF.
Remote cache: CI runners start with empty caches. --cache-to type=registry,ref=ghcr.io/acme/api:buildcache,mode=max exports every layer's cache, and --cache-from with the same ref imports it on the next run (type=gha exists for GitHub Actions). Cache export to registries needs a builder using the docker-container driver or the containerd image store.
docker buildx du and docker buildx prune manage the builder's cache.
Example
# syntax=docker/dockerfile:1
FROM python:3.13-slim
WORKDIR /app
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
rm -f /etc/apt/apt.conf.d/docker-clean && \
apt-get update && apt-get install -y --no-install-recommends git
RUN --mount=type=cache,target=/root/.cache/pip \
--mount=type=bind,source=requirements.txt,target=requirements.txt \
--mount=type=secret,id=pipconf,target=/etc/pip.conf \
pip install -r requirements.txt
COPY . .
CMD ["python", "main.py"]
# docker build --secret id=pipconf,src=$HOME/.config/pip/pip.conf \
# --cache-from type=registry,ref=ghcr.io/acme/app:cache \
# --cache-to type=registry,ref=ghcr.io/acme/app:cache,mode=max -t app .Remember
- RUN --mount=type=cache keeps package caches warm across builds
- Secret and SSH mounts give a single step access without leaking into layers
- Export/import cache to a registry so CI builds aren't cold
- Begin Dockerfiles with # syntax=docker/dockerfile:1
Watch out for
- Expecting a cache mount's contents to be in the final image — they're only available during that RUN.