Docker Multi-Stage Builds: Smaller Images, Cleaner Dockerfiles

A typical Go application compiles to a single binary. Yet Docker images for Go apps often weigh hundreds of megabytes. Why? Because the image includes the entire Go toolchain used to build it. Multi-stage builds solve this: use one stage to build, another to run. The final image contains only what’s needed at runtime. The Problem: Fat Images 1 2 3 4 5 6 7 8 # Single-stage - includes everything FROM golang:1.21 WORKDIR /app COPY . . RUN go build -o server . CMD ["./server"] This image includes: ...

February 23, 2026 Â· 5 min Â· 1034 words Â· Rob Washington

Container Image Security: Scanning Before You Ship

Every container image you deploy is a collection of dependencies you didn’t write. Some of those dependencies have known vulnerabilities. The question isn’t whether your images have CVEs — it’s whether you know about them before attackers do. The Problem A typical container image includes: A base OS (Alpine, Debian, Ubuntu) Language runtime (Python, Node, Go) Application dependencies (npm packages, pip modules) Your actual code Each layer can introduce vulnerabilities. That innocent FROM python:3.11 pulls in hundreds of packages you’ve never audited. ...

February 22, 2026 Â· 6 min Â· 1223 words Â· Rob Washington

Container Security Best Practices: Hardening Your Docker Images

A container is only as secure as its weakest layer. Most security breaches don’t exploit exotic vulnerabilities — they walk through doors left open by default configurations, bloated images, and running as root. Here’s how to actually secure your containers. Start with Minimal Base Images Every package in your image is attack surface. Alpine Linux images are ~5MB compared to Ubuntu’s ~70MB. Fewer packages means fewer CVEs to patch. 1 2 3 4 5 6 7 8 9 10 11 12 # ❌ Don't do this FROM ubuntu:latest RUN apt-get update && apt-get install -y python3 python3-pip COPY . /app CMD ["python3", "/app/main.py"] # ✅ Do this FROM python:3.12-alpine COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . /app CMD ["python3", "/app/main.py"] For compiled languages, use multi-stage builds to ship only the binary: ...

February 18, 2026 Â· 5 min Â· 1019 words Â· Rob Washington

Container Image Optimization: From 1.2GB to 45MB

That 1.2GB Python image you’re pushing to production? It contains gcc, make, and half of Debian’s package repository. Your application needs none of it at runtime. Container image optimization isn’t just about saving disk space—it’s about security (smaller attack surface), speed (faster pulls and deploys), and cost (less bandwidth and storage). Let’s fix it. The Problem: Development vs Runtime A typical Dockerfile grows organically: 1 2 3 4 5 6 7 8 9 # The bloated approach FROM python:3.11 WORKDIR /app COPY requirements.txt . RUN pip install -r requirements.txt COPY . . CMD ["python", "app.py"] This image includes: ...

February 12, 2026 Â· 5 min Â· 921 words Â· Rob Washington

Container Security: Hardening Your Docker Images and Kubernetes Deployments

Containers aren’t inherently secure. A default Docker image runs as root, includes unnecessary packages, and exposes more attack surface than needed. Let’s fix that. Secure Dockerfile Practices Use Minimal Base Images 1 2 3 4 5 6 7 8 # BAD: Full OS with unnecessary packages FROM ubuntu:latest # BETTER: Slim variant FROM python:3.11-slim # BEST: Distroless (no shell, no package manager) FROM gcr.io/distroless/python3-debian11 Size comparison: ubuntu:latest: ~77MB python:3.11-slim: ~45MB distroless/python3: ~16MB Smaller image = smaller attack surface. ...

February 11, 2026 Â· 5 min Â· 1030 words Â· Rob Washington

Docker Demystified: Why Containers Changed Everything

A practical introduction to Docker containers — what they are, why they matter, and how to start using them today.

February 10, 2026 Â· 7 min Â· 1298 words Â· Rob Washington