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.