InterviewHubPRO
Section Overview
Q4

Question 4 of 50

Part 1: Candid Experience, Container Internals & Docker (1 - 10)

8%
DevOps & Kubernetes (50 Qs)•Part 1: Candid Experience, Container Internals & Docker (1 - 10)

How do you optimize Dockerfiles for minimum image size, security, and build layer caching in production?

Production Best Practices & Dockerfile Blueprint

To achieve sub-50MB production images with fast CI build times and minimal vulnerabilities, follow four core rules:

  1. Order layers from least frequent to most frequent change to maximize Docker cache hits.
  2. Use Multi-Stage Builds to completely discard build tools, compilers, and devDependencies from the final runtime image.
  3. Use Distroless or Minimal Alpine/Scratch images to reduce CVE vulnerability surface.
  4. Never run as root; specify a non-root system user.
dockerfile
# -------------------------------------------------------------------
# STAGE 1: Builder (Compiles TypeScript & installs dependencies)
# -------------------------------------------------------------------
FROM node:20-alpine AS builder
WORKDIR /app

# Step 1: Copy dependency definitions first (cached unless package.json changes)
COPY package.json package-lock.json ./
RUN npm ci --prefer-offline --no-audit

# Step 2: Copy source code and compile
COPY tsconfig.json ./
COPY src/ ./src
RUN npm run build && npm prune --production

# -------------------------------------------------------------------
# STAGE 2: Minimal Production Runtime (Distroless or Non-Root Alpine)
# -------------------------------------------------------------------
FROM gcr.io/distroless/nodejs20-debian12:nonroot AS runner
WORKDIR /app

ENV NODE_ENV=production
ENV PORT=3000

# Copy only production node_modules and compiled output from builder
COPY --from=builder --chown=nonroot:nonroot /app/node_modules ./node_modules
COPY --from=builder --chown=nonroot:nonroot /app/dist ./dist
COPY --from=builder --chown=nonroot:nonroot /app/package.json ./package.json

# Run as nonroot user (UID 65532 built into distroless)
USER nonroot
EXPOSE 3000

CMD ["dist/main.js"]

Optimization Matrix

TechniqueProblem SolvedImpact
npm ci vs npm installDeterministic builds from lockfilePrevents silent version drift
Multi-Stage BuildLeaves compilers (gcc, tsc, devDependencies) behindReduces image size from ~900MB to ~70MB
.dockerignorePrevents copying local node_modules, .git, .envAvoids cache invalidation & secret leaks
Distroless BaseEliminates shell (/bin/sh), package managers (apt, apk)Attackers cannot execute reverse shells