Command Palette

Search for a command to run...

Hectal
PHASE 10Advanced ~8 min· topic 1 of 4

Topic 10.1

BuildKit & buildx: Multi-Arch, Cache Mounts & Build Secrets

In one line

BuildKit is Docker's modern build engine: parallel stages, cache mounts that keep dependency caches between builds, secret mounts that never land in layers, and buildx for multi-architecture images and shared remote caches in CI.

0/4 · 0%

Think of it like this

A bakery upgrading from one baker to a production kitchen. Independent steps happen in parallel (stages), the flour store is kept between batches instead of being thrown away (cache mounts), the recipe's secret ingredient is brought in for mixing and never printed on the label (secret mounts), and the same recipe bakes for two different ovens (multi-arch).

Key ideas

  1. 01

    BuildKit is the default builder in current Docker. It builds independent stages in parallel and skips stages the final target doesn't need. Enable features with the syntax line # syntax=docker/dockerfile:1.

  2. 02

    CACHE MOUNTS: RUN --mount=type=cache,target=/root/.m2 mvn -B package keeps Maven's local repository between builds without putting it in the image, so dependencies download once even when pom.xml changes. The same works for npm (/root/.npm), pip, Go, and apt.

  3. 03

    SECRET MOUNTS: RUN --mount=type=secret,id=npmrc,target=/root/.npmrc npm ci makes a secret available during that one step only; it never appears in any layer or in docker history (unlike ARG/ENV, which leak: DevSecOps course, secret in image layer). Pass it with docker build --secret id=npmrc,src=$HOME/.npmrc. SSH mounts (--mount=type=ssh) do the same for private Git dependencies.

  4. 04

    MULTI-ARCH with buildx: docker buildx build --platform linux/amd64,linux/arm64 -t registry/app:1.4.0 --push . builds one image index with variants for Intel/AMD and ARM (Graviton servers, Apple Silicon laptops). Cross-builds use QEMU emulation (slow) or native builders per architecture (fast).

  5. 05

    REMOTE CACHE for CI: ephemeral CI runners lose the local cache every run. --cache-to type=registry,ref=registry/app:buildcache,mode=max and --cache-from the same ref share layer cache across runs and runners (or type=gha on GitHub Actions), often turning 8-minute builds into 1-minute builds (CI/CD course, caching).

In your stack

  • →

    For Maven, combine a cache mount on /root/.m2 with Spring Boot layered JARs (Phase 6): dependency resolution is cached by BuildKit, and the dependency layer is reused across releases, so only your classes change.

Code & diagrams

Dockerfile with cache and secret mountsdockerfile
# syntax=docker/dockerfile:1
FROM maven:3.9-eclipse-temurin-21 AS build
WORKDIR /src
COPY pom.xml .
RUN --mount=type=cache,target=/root/.m2 mvn -B -q dependency:go-offline
COPY src ./src
RUN --mount=type=cache,target=/root/.m2 \
    --mount=type=secret,id=maven_settings,target=/root/.m2/settings.xml \
    mvn -B -q package -DskipTests

FROM eclipse-temurin:21-jre
RUN useradd -r -u 10001 app
COPY --from=build /src/target/app.jar /app/app.jar
USER 10001
ENTRYPOINT ["java", "-XX:MaxRAMPercentage=75", "-jar", "/app/app.jar"]
multi-arch build with a registry cachebash
docker buildx create --name ci --use
docker buildx build \
  --platform linux/amd64,linux/arm64 \
  --secret id=maven_settings,src=$HOME/.m2/settings.xml \
  --cache-from type=registry,ref=ghcr.io/shoplite/api:buildcache \
  --cache-to   type=registry,ref=ghcr.io/shoplite/api:buildcache,mode=max \
  -t ghcr.io/shoplite/api:sha-3f2a1c9 --push .
docker buildx imagetools inspect ghcr.io/shoplite/api:sha-3f2a1c9   # shows both platforms

Explain it without notes

01

Why is passing a token with ARG unsafe, and how do secret mounts fix it?

02

What's the difference between the layer cache and a cache mount?

Practice

01

Your CI builds on amd64 but production moved to Graviton (arm64) and the container fails with 'exec format error'. Fix the pipeline.

Trade-offs

  • ↔

    Multi-arch builds widen where images run and enable cheaper ARM instances, at the cost of longer builds (emulation) or extra runners; remote caches speed CI but add registry storage.

Done when you can

  • I use cache mounts for dependency managers and secret mounts for credentials

  • I can build and inspect a multi-arch image with buildx and a remote cache