Docker Multi-Stage Builds: Smaller Images, Faster Deploys

Your Docker images are probably too big. Most applications ship with compilers, package managers, and debug tools that never run in production. Multi-stage builds fix this by separating your build environment from your runtime environment. The Problem with Single-Stage Builds Here’s a typical Node.js Dockerfile: 1 2 3 4 5 6 7 8 FROM node:20 WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build EXPOSE 3000 CMD ["node", "dist/index.js"] This works, but the resulting image includes: ...

March 9, 2026 Â· 5 min Â· 961 words Â· Rob Washington

Docker Secrets Management: From Development to Production

Secrets management in Docker is where most teams get bitten. Environment variables leak into logs, credentials end up in images, and “it works on my machine” becomes a security incident. Here’s how to handle secrets properly at every stage. The Problem with Environment Variables The most common approach—and the most dangerous: 1 2 3 4 5 6 # docker-compose.yml - DON'T DO THIS services: app: environment: - DATABASE_PASSWORD=super_secret_password - API_KEY=sk-live-1234567890 Why this fails: ...

March 7, 2026 Â· 5 min Â· 944 words Â· Rob Washington

Docker Compose Patterns for Production

Docker Compose is often dismissed as “just for development,” but with the right patterns it handles production workloads well. Here are patterns that have survived contact with real systems. Service Dependencies Done Right The basic depends_on only waits for the container to start, not for the service to be ready: 1 2 3 4 5 6 7 # This doesn't guarantee postgres is accepting connections services: app: depends_on: - db db: image: postgres:15 Use health checks for real dependency management: ...

March 5, 2026 Â· 4 min Â· 832 words Â· Rob Washington

Kubernetes Troubleshooting: A Practical Field Guide

Kubernetes failures are rarely mysterious once you know where to look. The problem is knowing where to look. This guide covers the systematic approach to diagnosing common Kubernetes issues. The Diagnostic Hierarchy Start broad, drill down: C l u s t e r → N o d e → P o d → C o n t a i n e r → A p p l i c a t i o n At each level, the same questions apply: ...

March 5, 2026 Â· 6 min Â· 1234 words Â· Rob Washington

Container Security: Practical Hardening for Production

Containers provide isolation, but they’re not magic security boundaries. A misconfigured container can expose your entire host. Let’s fix that. Don’t Run as Root The single biggest mistake: running containers as root. 1 2 3 4 5 6 7 8 9 10 11 12 # Bad: runs as root by default FROM node:20 COPY . /app CMD ["node", "server.js"] # Good: create and use non-root user FROM node:20 RUN groupadd -r appgroup && useradd -r -g appgroup appuser WORKDIR /app COPY --chown=appuser:appgroup . . USER appuser CMD ["node", "server.js"] Why it matters: if an attacker escapes the container while running as root, they’re root on the host. As a non-root user, they’re limited. ...

March 4, 2026 Â· 5 min Â· 1063 words Â· Rob Washington

Docker Multi-Stage Builds: Smaller Images, Faster Deploys

Your Docker images are probably too big. Build tools, dev dependencies, source files—all shipping to production when only the compiled binary matters. Multi-stage builds fix this by separating build environment from runtime environment. The Problem A typical single-stage Dockerfile: 1 2 3 4 5 6 7 8 9 FROM python:3.11 WORKDIR /app COPY requirements.txt . RUN pip install -r requirements.txt COPY . . CMD ["python", "app.py"] This image includes: ...

March 1, 2026 Â· 4 min Â· 852 words Â· Rob Washington

Kubernetes Troubleshooting Patterns for Production

Kubernetes hides complexity until something breaks. Then you need to know where to look. Here’s a systematic approach to debugging production issues. The Debugging Hierarchy Start broad, narrow down: Cluster level: Nodes healthy? Resources available? Namespace level: Deployments running? Services configured? Pod level: Containers starting? Logs clean? Container level: Process running? Resources sufficient? Quick Health Check 1 2 3 4 5 6 7 8 9 10 11 # Node status kubectl get nodes -o wide # All pods across namespaces kubectl get pods -A # Pods not running kubectl get pods -A | grep -v Running | grep -v Completed # Events (recent issues) kubectl get events -A --sort-by='.lastTimestamp' | tail -20 Pod Troubleshooting Pod States State Meaning Check Pending Can’t be scheduled Resources, node selectors, taints ContainerCreating Image pulling or volume mounting Image name, pull secrets, PVCs CrashLoopBackOff Container crashing repeatedly Logs, resource limits, probes ImagePullBackOff Can’t pull image Image name, registry auth Error Container exited with error Logs Pending Pods 1 2 3 4 5 6 7 8 9 10 11 12 13 14 # Why is it pending? kubectl describe pod my-pod # Look for: # - Insufficient cpu/memory # - No nodes match nodeSelector # - Taints not tolerated # - PVC not bound # Check node resources kubectl describe nodes | grep -A5 "Allocated resources" # Check PVC status kubectl get pvc CrashLoopBackOff 1 2 3 4 5 6 7 8 9 10 11 12 13 14 # Get logs from current container kubectl logs my-pod # Get logs from previous (crashed) container kubectl logs my-pod --previous # Get logs from specific container kubectl logs my-pod -c my-container # Follow logs kubectl logs -f my-pod # Last N lines kubectl logs --tail=100 my-pod Common causes: ...

February 28, 2026 Â· 6 min Â· 1185 words Â· Rob Washington

Docker Compose Patterns for Local Development

Docker Compose turns “works on my machine” into “works everywhere.” Here’s how to structure it for real development workflows. Basic Structure 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 # docker-compose.yml services: app: build: . ports: - "3000:3000" volumes: - .:/app environment: - NODE_ENV=development db: image: postgres:15 environment: POSTGRES_PASSWORD: devpass Start everything: ...

February 28, 2026 Â· 6 min Â· 1088 words Â· Rob Washington

Container Health Check Patterns That Actually Work

Your container says it’s healthy. Your users say the app is broken. Sound familiar? Basic health checks only tell you if a process is running. Here’s how to build checks that catch real problems. Beyond “Is It Alive?” Most health checks look like this: 1 HEALTHCHECK CMD curl -f http://localhost:8080/health || exit 1 This tells you the HTTP server responds. It doesn’t tell you: Can the app reach the database? Is the cache connected? Are critical background workers running? Is the disk filling up? Layered Health Checks Implement three levels: ...

February 28, 2026 Â· 4 min Â· 744 words Â· Rob Washington

Docker Multi-Stage Builds: Smaller Images, Cleaner Deploys

Your Docker images are probably too big. Mine were. Then I learned about multi-stage builds. The problem is simple: build tools bloat production images. You need Node.js and npm to build your React app, but you only need nginx to serve it. You need Go and its toolchain to compile, but the binary runs standalone. Every megabyte of build tooling in your production image is wasted space, slower deploys, and expanded attack surface. ...

February 27, 2026 Â· 4 min Â· 843 words Â· Rob Washington