Skip to main content

Building with BuildKit

1. Enabling BuildKit

Example: Enable BuildKit in Dockerfile

# syntax=docker/dockerfile:1
FROM alpine:latest
RUN echo "BuildKit is enabled"
Method Description Notes
DOCKER_BUILDKIT=1 Environment variable to enable BuildKit Set before running docker build
buildkit.toml Configuration file for BuildKit Located at ~/.docker/buildkit.toml
Note: BuildKit is enabled by default in Docker 20.10 and later.

2. Using BuildKit Syntax

Directive Description Example
FROM Sets the base image for the build FROM --platform=linux/amd64 ubuntu:20.04
ARG Defines a build-time variable ARG VERSION=latest
ENV Sets environment variables ENV NODE_ENV=production
RUN Executes commands during build RUN --mount=type=cache,target=/var/cache/apt apt-get update
COPY Copies files from host to container COPY --chown=1000:1000 . /app
ADD Similar to COPY but supports remote URLs and tar extraction ADD https://example.com/file.tar.gz /tmp/
WORKDIR Sets the working directory for subsequent instructions WORKDIR /app
EXPOSE Documents which ports the application listens on EXPOSE 8080
CMD Provides default command to run when container starts CMD ["npm", "start"]
ENTRYPOINT Sets the command to run when container starts ENTRYPOINT ["./run.sh"]

Example: Multi-stage build with BuildKit features

FROM --platform=linux/amd64 golang:1.21 AS builder
WORKDIR /app
COPY . .
RUN --mount=type=cache,target=/root/.cache/go-build go build -o main .

FROM --platform=linux/amd64 alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/main .
CMD ["./main"]
Note: BuildKit syntax supports advanced features like --mount for caching and multi-platform builds using --platform.
Warning: Ensure that all --platform values match the target architecture to avoid runtime issues.

3. Using Build Secrets

Secret Source Description Usage
--secret Pass a secret from the host filesystem to the build --secret id=secret-name,src=/path/to/secret
--secret id=secret-name,env=ENV_VAR_NAME Pass a secret from an environment variable to the build --secret id=api-key,env=API_KEY

Example: Using a file-based secret

docker build --secret id=ssh-key,src=/home/user/.ssh/id_rsa -t myapp .

Example: Using an environment variable as secret

export API_KEY=abc123
docker build --secret id=api-key,env=API_KEY -t myapp .
Note: Secrets are not stored in the image layer and are only available during the build process.
Warning: Ensure that secret files have appropriate permissions to prevent unauthorized access.

4. Mounting SSH Agent

Option Values Description
--mount=type=ssh --mount=type=ssh Mounts the SSH agent socket into the build container

Example: Using SSH mount in Docker Build

docker build --mount=type=ssh ...
Note: The SSH agent must be running and accessible for this to work.

5. Implementing Build Mounts

Mount Type Description Usage Notes
bind Mounts a file or directory from the host machine into the build context --mount=type=bind,source=/host/path,target=/container/path Useful for sharing source code or configuration files
tmpfs Mounts a temporary filesystem in memory for the build context --mount=type=tmpfs,target=/tmp Fast, ephemeral storage; not persisted in final image
cache Mounts a cache directory to speed up builds --mount=type=cache,source=cache-dir,target=/app/cache Improves build performance by reusing cached data
secret Mounts a secret file into the build context (e.g., API keys) --mount=type=secret,source=secret-file,target=/run/secrets/my-secret Securely injects sensitive data without exposing it in the image
ssh Mounts SSH agent socket to allow access to private repositories --mount=type=ssh,target=/run/ssh-agent Enables git operations using SSH keys during build

Example: Using bind mount to share source code

docker build --mount=type=bind,source=./src,target=/app/src -t my-app .

Example: Using cache mount for faster builds

docker build --mount=type=cache,source=npm-cache,target=/root/.npm -t my-app .
Note: Build mounts are only available when using BuildKit. Ensure BUILDKIT=1 is set or use --mount flag in build commands.

6. Caching Build Layers

Layer Type Description Caching Behavior Notes
RUN Executes commands in a new layer Cache invalidated if command or files change Use --mount=cache for persistent caches
COPY/ADD Copies files from host to image Cache invalidated if source files change Use --from=... to reuse layers from other stages
ENV Sets environment variables Cache invalidated if value changes Use ARG for build-time variables

Example: Caching RUN Commands

FROM alpine:latest
RUN apk update && apk add curl
RUN curl -O https://example.com/file.txt
Note: BuildKit caches layers based on the command and file contents. Changing any part of the command or files will invalidate the cache.

7. Using Inline Cache

Option Values Description
--cache-from type=registry,ref=... Specifies external cache sources to use for build steps
--cache-to type=registry,ref=... Specifies where to store cache after build

Example: Using inline cache with Dockerfile

FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["npm", "start"]

Example: Build with inline cache

docker build --cache-from type=registry,ref=myapp:latest-cache \
              --cache-to type=registry,ref=myapp:latest-cache \
              -t myapp .
Note: Inline cache requires a registry to store and retrieve cached layers.

8. Configuring Build Output

Option Values Description
--output type=local,dest=<path> Specify the output destination for the build artifacts
--output type=docker Push the built image directly to Docker daemon
--output type=image,name=<image-name> Save the image to the local registry
--output type=registry,ref=<image-ref> Push the image to a remote registry
--output type=oci,dest=<path> Save the image in OCI format to a directory

Example: Save image to local registry

docker buildx build --output type=image,name=myapp:latest .

Example: Push to remote registry

docker buildx build --output type=registry,ref=my-registry.com/myapp:latest .
Note: The --output option supports multiple formats and destinations. You can combine them using comma-separated values.
Warning: When pushing to a registry, ensure you have proper authentication configured for the target registry.

9. Using Build Contexts

Context Description Usage
build context Directory containing files needed for building an image Specified with --build-context or default .
context path Path to the build context directory Can be local or remote (e.g., Git repo)

Example: Specifying a build context

docker build --build-context mycontext=/path/to/context -t myimage .
Note: Build contexts can be specified using the --build-context flag to define named contexts with custom paths or sources.

Key Points

  • Build context includes all files needed for the build process
  • Can be a local directory or remote source (e.g., Git repository)
  • Use --build-context to define custom context paths

10. Building for Multiple Platforms

Platform Architecture OS Notes
linux/amd64 x86_64 Linux Most common for servers
linux/arm64 aarch64 Linux Used in ARM-based systems like Raspberry Pi
linux/386 i386 Linux Legacy 32-bit systems
windows/amd64 x86_64 Windows For Windows containers
darwin/amd64 x86_64 macOS For macOS native builds
darwin/arm64 aarch64 macOS Apple Silicon (M1/M2) builds

Example: Building for Multiple Platforms

docker buildx build --platform linux/amd64,linux/arm64 -t myapp:latest .
Note: BuildKit must be enabled to use --platform flag.
Warning: Ensure your application and dependencies are compatible with target platforms.

Key Points

  • Use --platform to build for multiple architectures
  • BuildKit is required for multi-platform builds
  • Supports cross-compilation for ARM, x86, and more

11. Optimizing Layer Caching

Directive Description Best Practice
FROM Sets the base image for subsequent instructions Pin to specific tags (e.g., node:18-alpine) to ensure reproducibility
COPY Copies files from the host into the image Use COPY --from=... to reuse layers from other builds
ADD Similar to COPY but supports remote URLs and tar extraction Avoid ADD unless needed; prefer COPY for clarity and control
RUN Executes commands in a new layer Chain multiple RUN commands with && to reduce layer count
WORKDIR Sets the working directory for subsequent instructions Use WORKDIR to avoid long paths in commands
ENV Sets environment variables Use ENV for values that change infrequently or are reused across layers

Example: Layer Caching Optimization

FROM node:18-alpine

# Set working directory
WORKDIR /app

# Copy package files first to leverage layer caching
COPY package*.json ./

# Install dependencies (only re-run if package files change)
RUN npm ci --only=production

# Copy application code after installing dependencies
COPY . .

# Expose port and start app
EXPOSE 3000
CMD ["npm", "start"]
Note: BuildKit uses a content-based hash to determine if a layer can be reused. Changes in any file or command will invalidate the cache and force rebuilding from that point.

12. Debugging Builds with Progress Output

Example: Enable detailed build progress

docker build --progress=plain .\n
Flag Description Values
--progress Controls the output format of build progress auto, plain, tty
Note: Using --progress=plain provides verbose output useful for debugging build issues.

Was this article helpful?