Multi-Stage Dockerfile
Use this for production-oriented Dockerfiles where build dependencies, runtime
dependencies, security, and cache behavior should be explicit.
Project Fit Check
Before writing a Dockerfile:
- Detect runtime, package manager, lockfile, build output, server command, and
required native dependencies.
- Read existing Dockerfiles, compose files, CI image build jobs, and deployment
docs.
- Preserve the project's base-image policy, registry, and runtime user model.
- Do not introduce Alpine, distroless, rootless, or monorepo pruning patterns
without checking framework/native dependency compatibility.
- If the image is deployed by CI, align build args, secrets, labels, and tags
with that pipeline.
Structure
Default shape:
base: shared runtime image and environment
deps: install dependencies from lockfile
build: copy source and build artifacts
runtime: copy only runtime files and run as non-root when possible
Keep dependency install before source copy so source changes do not invalidate
the dependency cache.
Rules
- Use the lockfile with the matching package manager.
- Copy only needed files between stages.
- Keep build secrets out of final layers.
- Use
.dockerignore to exclude node_modules, build output, VCS metadata,
local env files, and caches.
- Prefer explicit
CMD and documented EXPOSE.
- Use health checks only when the deployment platform respects them.
- Add OCI labels if the registry/deploy process uses them.
Security
- Avoid root in the final image when the runtime allows it.
- Never bake
.env, tokens, SSH keys, or registry credentials into layers.
- Keep package manager caches out of the final image.
- Pin base image by digest when supply-chain policy requires reproducibility.
- Rebuild regularly for base image security patches.
Verification
docker build -t local-test .
docker run --rm local-test <smoke command>
For web services, run the container and hit a health or homepage route.
Red Flags
- one-stage image with compilers and dev dependencies in production
COPY . . before dependency install
- missing
.dockerignore
- final image runs as root without a reason
- secrets passed via
ARG and kept in image history
- container command differs from documented deploy command
1---2name: multi-stage-dockerfile3description: Creates and reviews secure, cache-friendly multi-stage Dockerfiles for Node, web, backend, and static-site projects. Use when writing Dockerfiles, optimizing image size, separating build/runtime stages, hardening containers, fixing slow Docker builds, or preparing production images.4---56# Multi-Stage Dockerfile78Use this for production-oriented Dockerfiles where build dependencies, runtime9dependencies, security, and cache behavior should be explicit.1011## Project Fit Check1213Before writing a Dockerfile:14151. Detect runtime, package manager, lockfile, build output, server command, and16 required native dependencies.172. Read existing Dockerfiles, compose files, CI image build jobs, and deployment18 docs.193. Preserve the project's base-image policy, registry, and runtime user model.204. Do not introduce Alpine, distroless, rootless, or monorepo pruning patterns21 without checking framework/native dependency compatibility.225. If the image is deployed by CI, align build args, secrets, labels, and tags23 with that pipeline.2425## Structure2627Default shape:28291. `base`: shared runtime image and environment302. `deps`: install dependencies from lockfile313. `build`: copy source and build artifacts324. `runtime`: copy only runtime files and run as non-root when possible3334Keep dependency install before source copy so source changes do not invalidate35the dependency cache.3637## Rules3839- Use the lockfile with the matching package manager.40- Copy only needed files between stages.41- Keep build secrets out of final layers.42- Use `.dockerignore` to exclude `node_modules`, build output, VCS metadata,43 local env files, and caches.44- Prefer explicit `CMD` and documented `EXPOSE`.45- Use health checks only when the deployment platform respects them.46- Add OCI labels if the registry/deploy process uses them.4748## Security4950- Avoid root in the final image when the runtime allows it.51- Never bake `.env`, tokens, SSH keys, or registry credentials into layers.52- Keep package manager caches out of the final image.53- Pin base image by digest when supply-chain policy requires reproducibility.54- Rebuild regularly for base image security patches.5556## Verification5758```bash59docker build -t local-test .60docker run --rm local-test <smoke command>61```6263For web services, run the container and hit a health or homepage route.6465## Red Flags6667- one-stage image with compilers and dev dependencies in production68- `COPY . .` before dependency install69- missing `.dockerignore`70- final image runs as root without a reason71- secrets passed via `ARG` and kept in image history72- container command differs from documented deploy command