Cloud Architecture10 min readPublished: 2026-09-18

Optimizing Docker Images: Multi-Stage Builds, Minimal Bases, and Security Hardening

Drastically reduce container image sizes from 1.2 GB to under 80 MB while eliminating OS CVE vulnerabilities using Distroless, Alpine, and proper build caching.

CPL

CloudPlatformLabs Engineering

Platform Architecture Team

Back to all guides

1. The Anatomy of a Bloated Container

A naive Dockerfile packages Node.js runtimes, npm build caches, C++ compiler toolchains (node-gyp), TypeScript compilers, test files, and package documentation into the final runtime container. This results in gigabyte-sized images, slow deployment pull times, and an enormous attack surface with hundreds of unnecessary OS packages.

Multi-stage builds split the compilation phase from the execution runtime. The build stage retains compilers and build dependencies, while the final stage copies only the compiled output and production-only dependencies.

Dockerfile
# Stage 1: Dependency resolution
FROM node:20-alpine AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --only=production

# Stage 2: Code Compilation
FROM node:20-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build

# Stage 3: Minimal Production Runtime
FROM gcr.io/distroless/nodejs20-debian12:nonroot AS runner
WORKDIR /app
ENV NODE_ENV=production
COPY --from=deps /app/node_modules ./node_modules
COPY --from=builder /app/dist ./dist
USER nonroot
EXPOSE 3000
CMD ["dist/server.js"]

2. Why Distroless Containers Win on Security

Distroless images, maintained by Google, contain only your application runtime and minimal shared libraries. They contain no package manager (apt/apk), no shell (bash/sh), and no system binaries. If an attacker discovers a Remote Code Execution (RCE) flaw, they cannot spawn an interactive shell or download malicious binaries via curl.

  • Zero interactive shell binaries (sh/bash) to frustrate lateral movement attacks.
  • Dramatic CVE reduction: base image vulnerability scan counts drop from 100+ down to 0.
  • Enforces non-root user execution out-of-the-box.

Related Topics & Tags

DockerContainersSecurityDevOpsNode.jsPerformance
CPL

Written by CloudPlatformLabs Engineering

Platform Architecture Team

CloudPlatformLabs publishes independent, peer-reviewed cloud and DevOps architecture blueprints, hands-on tutorials, and infrastructure case studies. Our mission is to make advanced infrastructure engineering transparent, resilient, and developer-friendly.