< cd ../blog
Apr 08#docker#ci-cd

Optimizing Docker Build Caches for 10x Faster CI

Slow builds are a tax on every single commit. We took a 9-minute image build down to under a minute with three changes.

1. Order layers by change frequency

Put the things that rarely change first. Dependencies before source code.

FROM node:20-slim
WORKDIR /app

# Changes rarely — cached almost always
COPY package.json bun.lock ./
RUN bun install --frozen-lockfile

# Changes often — only this layer rebuilds
COPY . .
RUN bun run build

2. Use BuildKit cache mounts

Cache mounts persist package manager state across builds without baking it into the image.

RUN --mount=type=cache,target=/root/.bun/install/cache \
    bun install --frozen-lockfile

3. Cache to your registry

In CI, pull the previous image as a cache source:

docker buildx build \
  --cache-from type=registry,ref=ghcr.io/acme/web:cache \
  --cache-to type=registry,ref=ghcr.io/acme/web:cache,mode=max \
  -t ghcr.io/acme/web:$SHA .

The result: cold builds stay fast, and warm builds are nearly instant.