✦ For everyone, free.

Practical knowledge for real and everyday life

Home

12.2.2.4 Node Production Stage

A focused guide to Node Production Stage, connecting core concepts with practical Docker and container operations.

A Node production stage is the final, minimal stage of a multi-stage Node.js Dockerfile, containing only the built application output and production dependencies, without the development tooling, source maps, or build-time dependencies used to produce that output.

Structuring the Production Stage

The production stage starts fresh from a clean base image, copying in only what's actually needed at runtime.

FROM node:20-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY --from=build /app/dist ./dist
CMD ["node", "dist/server.js"]

The production stage installs only production dependencies and copies only the built dist output, excluding the build stage's larger set of development dependencies and original, unbuilt source files.

Why This Separation Reduces the Final Image's Size and Surface

Development dependencies — testing frameworks, linters, build tools — are often substantial in size and entirely unnecessary at runtime, making their exclusion from the production stage both a size and security benefit.

docker images
myapp-build      850MB
myapp-production 180MB
Running the Production Stage as a Non-Root User

The production stage should also apply runtime security practices like non-root execution, independent of whatever user context the build stage used.

USER node
CMD ["node", "dist/server.js"]
Verifying the Production Stage Contains Only What's Needed

Reviewing the final image's contents confirms no unnecessary build-time artifacts were inadvertently carried forward.

docker run --rm myapp:1.0 ls -la /app
Why a Node Production Stage Matters

A properly minimized production stage is the actual deliverable of a Node.js multi-stage build, and getting it right — excluding development dependencies, applying runtime security practices — is essential for producing an efficient, appropriately scoped final image.