DevOps
Multi-stage builds that actually shrink your image size
The difference between a 1.2GB image and a 120MB one is usually one Dockerfile pattern, not a different base image.
Last updated September 17, 2026
The most common reason a Docker image is huge isn't the base image — it's that the compiler, package manager cache, and every dev dependency used to build the app are still sitting in the final image, because a single-stage Dockerfile has no way to leave them behind.
How it happens
A typical single-stage Dockerfile installs dependencies, copies source, builds, and that's the image you ship — with the entire node_modules dev tree, build tooling, and intermediate artifacts baked in, none of which the running app needs. For a Node app this alone can be the difference between a few hundred megabytes and well over a gigabyte.
The multi-stage pattern
A build stage does the heavy lifting, and a separate, minimal final stage copies out only what's needed to run:
# build stage
FROM node:20 AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# runtime stage
FROM node:20-slim
WORKDIR /app
COPY --from=build /app/dist ./dist
COPY --from=build /app/package*.json ./
RUN npm ci --omit=dev
CMD ["node", "dist/index.js"]
The build stage's entire filesystem — dev dependencies, source maps, the compiler cache — never makes it into the final image. Only COPY --from=build results do, and only the specific paths named.
Copy less than you think you need
The remaining mistake, even with multi-stage builds, is copying too broadly — COPY --from=build /app ./ instead of naming the specific build output directory. That drags along test files, config that's only needed at build time, and anything else that happened to be sitting in the build stage's working directory. Naming exact paths is more typing and it's the difference between an image that ships what you meant to ship and one that ships whatever happened to be lying around.
Switching to a slim or alpine base for the runtime stage helps too, but it's a smaller win than people expect — the multi-stage split itself is usually where most of the size actually goes.
Tags
Related posts