# Why change your Dockerfile Most single-stage Node Dockerfiles keep the entire build shop in the final image: the Debian base, full Node toolchain, compilers, dev dependencies, npm cache, and your full source tree. That often turns a tiny app into a 1+ GB image. The consequences: slower pulls during deploys and autoscaling, more layers for scanners, larger attack surface, and longer time between push and running.
# What multi-stage builds do A multi-stage Dockerfile uses multiple FROM instructions. Do the heavy work in an early stage (install, compile), then start a fresh final stage and copy only what you actually need to run. The build-stage layers never make it into the final image.
- Stage 1 (named build): FROM node:20 AS build — install dependencies including dev, run build steps.
This pattern keeps compilers, dev packages, npm cache, and full source out of the runtime image.
# Four implementation details that matter
2) Don't copy node_modules between stages
3) Order instructions to maximize cache reuse Docker caches layers top to bottom. Copy lockfiles and install dependencies before copying the rest of your source. That way a code change invalidates only the later layers and doesn't force a full reinstall.
If you reverse that, every small change triggers a full dependency reinstall.
4) Choose a smaller final base and drop root
# Other useful patterns
- Multiple build targets: add a test stage (FROM build AS test) that runs linters and unit tests. CI can build only that --target test.
# What you get in practice Measured on an Express + TypeScript example in the article:
- Single-stage node:20: ~1.1 GB
- Multi-stage with node:20-slim and --omit=dev: ~180 MB
- Multi-stage with distroless final: ~130 MB
# Practical checklist before you change a Dockerfile
- Add a build stage: FROM node: AS build.
- Install and build in build stage.
- Keep install layer above COPY.. to preserve cache.
- Use a non-root USER in the final stage.
A small, ten-line change yields smaller images, faster deploys, and fewer runtime liabilities.