Loading…
Loading…
Reduce your Node.js Docker image size by 80% using multi-stage builds that separate build dependencies from production runtime artifacts.
Tags
Use a multi-stage Dockerfile to build in a full Node.js image and run in a slim one, cutting your final image size by 80% or more.
A typical Node.js Dockerfile installs all dependencies (including devDependencies), copies the full source, and builds in a single image. The result is a 1GB+ image that ships TypeScript, testing tools, build scripts, and source files that your production app never touches. Larger images mean slower deployments, higher storage costs, and a bigger attack surface.
Split your Dockerfile into three stages -- dependencies, build, and production:
# Stage 1: Install dependencies
FROM node:20-alpine AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
# Stage 2: Build the application
FROM node:20-alpine AS build
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build
# Stage 3: Production image
FROM node:20-alpine AS production
WORKDIR /app
ENV NODE_ENV=production
# Only copy what's needed to run
COPY --from=deps /app/node_modules ./node_modules
COPY --from=build /app/dist ./dist
COPY package.json ./
# Remove devDependencies
RUN npm prune --omit=dev
USER node
EXPOSE 3000
CMD ["node", "dist/server.js"]Build and check the size difference:
docker build -t myapp .
docker images myapp # typically 150-200MB vs 1GB+Each FROM statement starts a fresh filesystem layer. The final production stage only contains the alpine base, production node_modules, and compiled output. All build tools (TypeScript, ESLint, testing frameworks) and source files are left behind in the earlier stages. Docker discards those intermediate stages from the final image entirely, so they add zero bytes to what you ship. The npm prune --omit=dev step ensures even transitive devDependencies are stripped out.
Collaboration
I help startups and established companies design, build, and scale world-class digital products. From deep technical architecture to pixel-perfect UI: let's bring your vision to life.
Five essential built-in generic utility types in TypeScript that will save you hundreds of lines of code.
Generate dynamic Open Graph images in Next.js using the ImageResponse API with custom fonts, gradients, and data-driven content for social sharing.
Create reusable GitHub Actions workflows with inputs, secrets, and outputs to eliminate YAML duplication across repositories and teams efficiently.