AcademyContainment Breach: The Architect's ShipZone 8: The Iron Curtain (Security)

Lesson 1: The Minimalist (Optimizing Docker Images)

A 2GB Docker image takes forever to pull, wastes disk space, and has a larger attack surface. Great DevOps engineers build small, efficient images. It's the art of minimalism.

The Size Problem

docker images --format 'table {{.Repository}}:{{.Tag}}\t{{.Size}}'
node:18              920MB   😱
node:18-slim         240MB   🤔
node:18-alpine        50MB   ✅

Strategy 1: Choose Small Base Images

| Base Image | Size | When to Use | |-----------|------|-------------| | ubuntu | ~78 MB | Learning, full toolset needed | | debian:slim | ~52 MB | Production, need apt | | alpine | ~5 MB | Production, minimal | | distroless | ~2 MB | Production, maximum security | | scratch | 0 MB | Static binaries (Go, Rust) |

Strategy 2: Multi-Stage Builds

The most powerful optimization. Build in one stage, deploy from another:

# ===== Stage 1: Build =====
FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# ===== Stage 2: Production =====
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
EXPOSE 3000
CMD ["node", "dist/server.js"]

Result: The final image only contains the built output, not the build tools, source code, or dev dependencies.

Without multi-stage:   920MB  (includes compilers, source, dev deps)
With multi-stage:       85MB  (only runtime + built code)

Strategy 3: Minimize Layers

Each RUN command creates a layer. Combine them:

# ❌ BAD: 3 layers
RUN apt-get update
RUN apt-get install -y curl
RUN rm -rf /var/lib/apt/lists/*

# ✅ GOOD: 1 layer
RUN apt-get update && \
    apt-get install -y curl && \
    rm -rf /var/lib/apt/lists/*

Strategy 4: Use .dockerignore

Like .gitignore for Docker builds. Prevents unnecessary files from being sent to the build context:

node_modules
.git
*.md
.env
.vscode
Dockerfile
docker-compose.yml

Strategy 5: Don't Install Unnecessary Packages

# ❌ Installs recommended packages too
RUN apt-get install python3

# ✅ Only install what's needed
RUN apt-get install --no-install-recommends python3
booting...

Mission Objective

Optimize like a pro:

  1. Audit: Compare image sizes with docker images --format 'table {{.Repository}}:{{.Tag}}\t{{.Size}}'.
  2. Analyze: View layers with docker history nginx --no-trunc.
  3. Ignore: Create a .dockerignore with echo 'node_modules\n.git\n*.md\n.env' > .dockerignore.

Mission Control

Compare image sizes

Expected Command

docker images --format 'table {{.Repository}}:{{.Tag}} {{.Size}}'

Analyze image layers

Create a .dockerignore file