Skip to content
Latchkey

How to Reduce Docker Image Size With a Multi-Stage Build in CI

A multi-stage build keeps compilers and dev dependencies out of the final image by copying only the built output forward.

Compile in a heavier builder stage, then COPY --from=builder only the runtime artifacts into a minimal base. The toolchain layers are discarded, shrinking the published image and its attack surface.

Steps

  • Name the build stage with FROM ... AS builder.
  • Install dependencies and build in that stage.
  • Start a slim final stage and COPY --from=builder only what runtime needs.

Dockerfile

Dockerfile
FROM node:20-bookworm AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build && npm prune --omit=dev

FROM node:20-bookworm-slim
WORKDIR /app
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/dist ./dist
CMD ["node", "dist/server.js"]

Gotchas

  • Only the final stage is published; earlier stages exist only to feed COPY --from.
  • A -slim or distroless base trims the runtime further, but verify required shared libraries are present.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →