From cf9385c68d389ce2dc351c57b7933d92b97081c2 Mon Sep 17 00:00:00 2001 From: bobbyonmagic Date: Sun, 1 Mar 2026 21:48:14 +0000 Subject: [PATCH] feat: Add advanced Docker features blog post (Issue #939) --- content/posts/advanced-docker-features.md | 713 ++++++++++++++++++ .../images/posts/advanced-docker-features.png | Bin 0 -> 34497 bytes .../images/posts/advanced-docker-features.svg | 32 + 3 files changed, 745 insertions(+) create mode 100644 content/posts/advanced-docker-features.md create mode 100644 public/images/posts/advanced-docker-features.png create mode 100644 public/images/posts/advanced-docker-features.svg diff --git a/content/posts/advanced-docker-features.md b/content/posts/advanced-docker-features.md new file mode 100644 index 00000000..33c1daf9 --- /dev/null +++ b/content/posts/advanced-docker-features.md @@ -0,0 +1,713 @@ +--- +title: '5 Advanced Docker Features Worth Knowing' +excerpt: 'Go beyond Docker basics with BuildKit, multi-stage builds, health checks, init processes, and build secrets. Learn practical techniques that improve security, performance, and reliability.' +category: + name: 'Docker' + slug: 'docker' +date: '2026-03-02' +publishedAt: '2026-03-02T11:00:00Z' +updatedAt: '2026-03-02T11:00:00Z' +readingTime: '12 min read' +author: + name: 'DevOps Daily Team' + slug: 'devops-daily-team' +tags: + - Docker + - DevOps + - Containers + - BuildKit + - Security +--- + +You know how to write a Dockerfile, run containers, and maybe even orchestrate them with Docker Compose. But Docker has evolved significantly, and many powerful features remain underutilized even by experienced users. These advanced capabilities can dramatically improve your container images' security, build times, and runtime reliability. + +Most teams stick with the basics because they work well enough. Yet investing time in these five advanced features pays dividends in production. Smaller images deploy faster and have fewer security vulnerabilities. Proper health checks prevent routing traffic to broken containers. Build secrets keep credentials out of your image layers forever. + +**TLDR**: This guide covers five advanced Docker features that improve production workloads. BuildKit's experimental syntax enables efficient caching and parallel builds. Multi-stage builds create minimal production images from complex build processes. Health checks let orchestrators verify container readiness. Init processes prevent zombie processes and ensure clean signal handling. Build secrets inject credentials during builds without leaking them into image layers. + +## Why Go Beyond Docker Basics + +Basic Docker usage, writing a Dockerfile with `FROM`, `RUN`, and `CMD`, works fine for development. But production environments demand more: images need to be small for fast deployment, builds need to be fast for rapid iteration, and containers need to handle signals properly for graceful shutdowns. + +Consider a typical scenario: your Node.js application container takes 5 minutes to build because it reinstalls all dependencies every time. Your 2GB image takes forever to push to your registry. In production, your application doesn't respond to termination signals properly, causing 30-second delays during deployments when Kubernetes forcefully kills pods. + +Each advanced feature addresses a specific pain point: +- **BuildKit** dramatically speeds up builds with better caching +- **Multi-stage builds** slash image sizes by 80-90% +- **Health checks** prevent traffic routing to broken containers +- **Init processes** ensure proper signal handling and prevent zombie processes +- **Build secrets** keep credentials out of images permanently + +These aren't theoretical improvements. Teams report build time reductions from 10 minutes to under 2 minutes, image size drops from 1.5GB to 200MB, and elimination of mysterious container startup failures. + +--- + +## 1. BuildKit: Next-Generation Image Builds + +BuildKit is Docker's modern build engine that replaces the legacy builder. It provides parallel builds, efficient caching, and advanced features like cache mounts and secret mounts. While it's now the default in recent Docker versions, many developers don't leverage its full capabilities. + +### Why BuildKit Matters + +The legacy builder processes Dockerfile instructions sequentially, rebuilding layers whenever anything changes. BuildKit builds multiple stages in parallel, skips unused stages entirely, and provides sophisticated cache management. + +**Legacy builder flow:** +``` +Step 1 → Step 2 → Step 3 → Step 4 → Step 5 +(5 sequential operations, ~8 minutes) +``` + +**BuildKit flow:** +``` +Step 1 → Step 2 ──┐ + ├→ Step 5 +Step 3 → Step 4 ──┘ +(parallel execution, ~3 minutes) +``` + +### Basic BuildKit Usage + +Enable BuildKit for a single build: +```bash +DOCKER_BUILDKIT=1 docker build -t myapp:latest . +``` + +Enable BuildKit by default: +```json +// ~/.docker/daemon.json +{ + "features": { + "buildkit": true + } +} +``` + +### Advanced: Cache Mounts + +Cache mounts persist directories between builds, perfect for package manager caches: + +```dockerfile +# syntax=docker/dockerfile:1 +FROM node:22-alpine + +WORKDIR /app + +# Cache npm packages between builds +RUN --mount=type=cache,target=/root/.npm \\ + npm install -g pnpm + +COPY package.json pnpm-lock.yaml ./ + +# Cache pnpm store between builds +RUN --mount=type=cache,target=/root/.local/share/pnpm/store \\ + pnpm install --frozen-lockfile + +COPY . . +RUN pnpm build + +CMD ["node", "dist/index.js"] +``` + +**Key points:** +- The `# syntax=docker/dockerfile:1` directive enables BuildKit features +- `--mount=type=cache` creates a persistent cache between builds +- The cache persists even when you change code or dependencies +- First build: 4 minutes, subsequent builds: 30 seconds + +### When BuildKit Doesn't Help + +BuildKit won't magically speed up inherently slow operations: +- Compiling large codebases still takes time +- Downloading gigabytes of data still requires bandwidth +- CPU-intensive operations run at the same speed + +The speedup comes from intelligent caching and parallelization, not from making individual operations faster. + +--- + +## 2. Multi-Stage Builds: Minimal Production Images + +Multi-stage builds use multiple `FROM` statements in a single Dockerfile, each starting a new build stage. You can copy artifacts from earlier stages into later ones, leaving behind build tools, source code, and temporary files. + +### The Problem Multi-Stage Builds Solve + +Traditional approach (the "fat image" problem): + +```dockerfile +FROM node:22 +WORKDIR /app +COPY package.json pnpm-lock.yaml ./ +RUN npm install -g pnpm && pnpm install +COPY . . +RUN pnpm build +CMD ["node", "dist/index.js"] +``` + +**Result:** 1.2GB image containing: +- Node.js (expected) +- All build tools (unnecessary in production) +- Source TypeScript files (not needed, we have compiled JS) +- node_modules with devDependencies (only need production deps) +- Build cache and temporary files (waste) + +### Multi-Stage Solution + +```dockerfile +# syntax=docker/dockerfile:1 + +# ======================================== +# Stage 1: Build +# ======================================== +FROM node:22-alpine AS builder + +WORKDIR /app + +# Install build dependencies +RUN npm install -g pnpm + +COPY package.json pnpm-lock.yaml ./ +RUN pnpm install --frozen-lockfile + +# Build application +COPY . . +RUN pnpm build + +# ======================================== +# Stage 2: Production +# ======================================== +FROM node:22-alpine AS production + +WORKDIR /app + +# Install only production dependencies +RUN npm install -g pnpm +COPY package.json pnpm-lock.yaml ./ +RUN pnpm install --frozen-lockfile --prod + +# Copy only built artifacts from builder stage +COPY --from=builder /app/dist ./dist + +# Run as non-root user +USER node + +CMD ["node", "dist/index.js"] +``` + +**Result:** 180MB image containing only: +- Node.js runtime +- Production dependencies +- Compiled JavaScript + +### Real-World Impact + +**Before multi-stage:** +- Image size: 1.2GB +- Docker pull: 2 minutes +- Vulnerabilities: 47 (including build tools) +- Pod startup time: 45 seconds + +**After multi-stage:** +- Image size: 180MB +- Docker pull: 12 seconds +- Vulnerabilities: 8 (only runtime deps) +- Pod startup time: 8 seconds + +### Advanced Pattern: Distroless Images + +For maximum security, use Google's distroless images that contain only your application and runtime dependencies: + +```dockerfile +# Build stage +FROM golang:1.23-alpine AS builder +WORKDIR /app +COPY go.mod go.sum ./ +RUN go mod download +COPY . . +RUN CGO_ENABLED=0 GOOS=linux go build -o /app/server . + +# Production stage +FROM gcr.io/distroless/static-debian12 +COPY --from=builder /app/server /server +USER nonroot:nonroot +CMD ["/server"] +``` + +Distroless images: +- Contain no shell, package manager, or utilities +- Drastically reduce attack surface +- Often under 50MB total +- Make container escape nearly impossible + +--- + +## 3. Health Checks: Verify Container Readiness + +Health checks tell Docker (and orchestrators like Kubernetes) whether your container is actually ready to serve traffic, not just that the process is running. + +### Why Process Running ≠ Application Ready + +Your container process might be running but: +- Still loading configuration files +- Connecting to databases (connection pool warming up) +- Populating caches +- Waiting for dependent services + +Without health checks, orchestrators route traffic immediately, causing: +- 502 Bad Gateway errors during deployments +- Failed requests during container restarts +- Cascading failures when containers aren't ready + +### Basic Health Check + +```dockerfile +FROM node:22-alpine +WORKDIR /app + +COPY package.json pnpm-lock.yaml ./ +RUN npm install -g pnpm && pnpm install --prod +COPY . . + +# Health check: curl the /health endpoint every 30 seconds +HEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3 \\ + CMD node -e "require('http').get('http://localhost:3000/health', (res) => process.exit(res.statusCode === 200 ? 0 : 1))" || exit 1 + +CMD ["node", "server.js"] +``` + +**Health check options:** +- `--interval=30s`: Check every 30 seconds +- `--timeout=3s`: Mark as failed if check takes >3 seconds +- `--start-period=40s`: Grace period for app startup (don't count failures) +- `--retries=3`: Fail after 3 consecutive failures + +### Application Health Endpoint + +Your application should implement a `/health` endpoint: + +```javascript +// server.js (Node.js example) +const express = require('express'); +const app = express(); + +// Health check endpoint +app.get('/health', async (req, res) => { + try { + // Check critical dependencies + await checkDatabaseConnection(); + await checkRedisConnection(); + + // Check application state + if (!app.locals.initialized) { + return res.status(503).json({ status: 'initializing' }); + } + + res.status(200).json({ + status: 'healthy', + uptime: process.uptime(), + timestamp: new Date().toISOString() + }); + } catch (error) { + res.status(503).json({ + status: 'unhealthy', + error: error.message + }); + } +}); +``` + +### What to Check in Health Endpoints + +**Do check:** +- Critical database connections +- Required message queues (Kafka, RabbitMQ) +- Disk space availability +- Application initialization state + +**Don't check:** +- External APIs (failure shouldn't mark your app unhealthy) +- Non-critical services (monitoring, logging) +- Expensive operations (health checks run frequently) + +### Docker Health Check Behavior + +```bash +# Check container health status +docker ps +# Shows: STATUS = Up 2 minutes (healthy) + +# View health check history +docker inspect --format='{{json .State.Health}}' container_name +``` + +When a container becomes unhealthy: +- Docker marks it unhealthy but keeps it running +- Orchestrators (Docker Swarm, Kubernetes) stop routing traffic +- Kubernetes can restart unhealthy containers automatically + +--- + +## 4. Init Process: Proper Signal Handling + +When you run a process as PID 1 in a container, it inherits special responsibilities from the Linux kernel. Most applications aren't designed to handle these responsibilities, leading to zombie processes and improper shutdowns. + +### The PID 1 Problem + +In Linux, PID 1 (init process) has special duties: +1. **Reap zombie processes**: Clean up terminated child processes +2. **Forward signals**: Properly handle SIGTERM, SIGINT, SIGKILL +3. **Adopt orphaned processes**: Become parent of orphaned children + +Most applications don't implement these behaviors: + +```dockerfile +FROM node:22-alpine +COPY app.js . +CMD ["node", "app.js"] # node runs as PID 1, doesn't handle signals well +``` + +**Problems:** +- `docker stop` waits 10 seconds then forcefully kills (SIGKILL) +- Zombie processes accumulate if your app spawns children +- Graceful shutdown logic never runs +- Database connections don't close properly + +### Solution 1: Use --init Flag + +```bash +docker run --init myapp:latest +``` + +Docker's built-in init process (tini) runs as PID 1 and properly forwards signals to your application. + +### Solution 2: Add tini to Your Image + +```dockerfile +FROM node:22-alpine + +# Install tini +RUN apk add --no-cache tini + +WORKDIR /app +COPY package.json pnpm-lock.yaml ./ +RUN npm install -g pnpm && pnpm install --prod +COPY . . + +# Use tini as entrypoint +ENTRYPOINT ["/sbin/tini", "--"] +CMD ["node", "server.js"] +``` + +### Solution 3: Implement Signal Handling + +For Node.js applications, handle signals explicitly: + +```javascript +// server.js +const express = require('express'); +const app = express(); + +const server = app.listen(3000, () => { + console.log('Server started on port 3000'); +}); + +// Graceful shutdown handler +const gracefulShutdown = (signal) => { + console.log(`Received ${signal}, starting graceful shutdown`); + + server.close(() => { + console.log('HTTP server closed'); + + // Close database connections + closeDatabase().then(() => { + console.log('Database connections closed'); + process.exit(0); + }); + }); + + // Force exit after 30 seconds + setTimeout(() => { + console.error('Forced shutdown after timeout'); + process.exit(1); + }, 30000); +}; + +// Handle termination signals +process.on('SIGTERM', () => gracefulShutdown('SIGTERM')); +process.on('SIGINT', () => gracefulShutdown('SIGINT')); +``` + +### Real-World Impact + +**Without init process:** +- `kubectl delete pod`: 10-second forced kill +- Active requests: terminated mid-flight +- Database connections: not closed properly +- Zombie processes: accumulate over time + +**With init process:** +- `kubectl delete pod`: 2-second graceful shutdown +- Active requests: complete before shutdown +- Database connections: closed cleanly +- Zombie processes: properly reaped + +--- + +## 5. Build Secrets: Keep Credentials Out of Images + +Build secrets inject sensitive data during the build process without storing it in image layers. This prevents credentials from leaking through image inspection or layer analysis. + +### The Problem: Secrets in Layers + +**Bad approach (credentials leaked forever):** + +```dockerfile +FROM node:22-alpine +WORKDIR /app + +# Copy credentials (they're now in this layer FOREVER) +COPY .npmrc ./ +RUN npm install +RUN rm .npmrc # Too late! It's in the previous layer +``` + +Even after deleting, the file exists in the layer: +```bash +# Anyone with image access can extract credentials +docker save myapp:latest | tar -x +# .npmrc is visible in layer tar archives +``` + +### Solution: BuildKit Secret Mounts + +```dockerfile +# syntax=docker/dockerfile:1 +FROM node:22-alpine +WORKDIR /app + +COPY package.json pnpm-lock.yaml ./ + +# Mount secret during build (not stored in layers) +RUN --mount=type=secret,id=npmrc,target=/root/.npmrc \\ + npm install -g pnpm && \\ + pnpm install --frozen-lockfile + +COPY . . +RUN pnpm build + +CMD ["node", "dist/index.js"] +``` + +Build with secret: +```bash +docker build --secret id=npmrc,src=.npmrc -t myapp:latest . +``` + +**How it works:** +1. BuildKit mounts `.npmrc` as a temporary file during `RUN` command +2. The file is only available during that specific `RUN` instruction +3. The secret is never written to any image layer +4. After the `RUN` completes, the secret is unmounted + +### Advanced: Multiple Secrets + +```dockerfile +# syntax=docker/dockerfile:1 +FROM python:3.12-alpine +WORKDIR /app + +COPY requirements.txt ./ + +# Use multiple secrets +RUN --mount=type=secret,id=pip_config,target=/etc/pip.conf \\ + --mount=type=secret,id=ssh_key,target=/root/.ssh/id_rsa \\ + pip install --no-cache-dir -r requirements.txt + +COPY . . +CMD ["python", "app.py"] +``` + +Build with multiple secrets: +```bash +docker build \\ + --secret id=pip_config,src=pip.conf \\ + --secret id=ssh_key,src=~/.ssh/id_rsa \\ + -t myapp:latest . +``` + +### CI/CD Integration + +**GitHub Actions example:** +```yaml +- name: Build with secrets + run: | + echo "${{ secrets.NPM_TOKEN }}" > .npmrc + docker build --secret id=npmrc,src=.npmrc -t myapp:latest . + rm .npmrc +``` + +**GitLab CI example:** +```yaml +build: + script: + - echo "$NPM_TOKEN" > .npmrc + - docker build --secret id=npmrc,src=.npmrc -t myapp:latest . + after_script: + - rm -f .npmrc +``` + +### Verify Secrets Don't Leak + +```bash +# Search for secret in all layers +docker history myapp:latest +docker save myapp:latest -o image.tar +tar -xf image.tar +grep -r "secret-pattern" . +# Should return nothing +``` + +--- + +## Combining These Features + +Here's a production-ready Dockerfile using all five features: + +```dockerfile +# syntax=docker/dockerfile:1 + +# ======================================== +# Build Stage +# ======================================== +FROM node:22-alpine AS builder + +WORKDIR /app + +# Install build tools with cache mount +RUN --mount=type=cache,target=/root/.npm \\ + npm install -g pnpm + +# Install dependencies with secret and cache +COPY package.json pnpm-lock.yaml ./ +RUN --mount=type=secret,id=npmrc,target=/root/.npmrc \\ + --mount=type=cache,target=/root/.local/share/pnpm/store \\ + pnpm install --frozen-lockfile + +COPY . . +RUN pnpm build + +# ======================================== +# Production Stage +# ======================================== +FROM node:22-alpine AS production + +# Install tini for proper signal handling +RUN apk add --no-cache tini + +WORKDIR /app + +# Install production dependencies only +RUN --mount=type=cache,target=/root/.npm \\ + npm install -g pnpm + +COPY package.json pnpm-lock.yaml ./ +RUN --mount=type=cache,target=/root/.local/share/pnpm/store \\ + pnpm install --frozen-lockfile --prod + +# Copy built application +COPY --from=builder /app/dist ./dist + +# Health check +HEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3 \\ + CMD node -e "require('http').get('http://localhost:3000/health', (res) => process.exit(res.statusCode === 200 ? 0 : 1))" + +# Run as non-root user +USER node + +# Use tini as init process +ENTRYPOINT ["/sbin/tini", "--"] +CMD ["node", "dist/index.js"] +``` + +Build command: +```bash +DOCKER_BUILDKIT=1 docker build \\ + --secret id=npmrc,src=.npmrc \\ + -t myapp:latest \\ + . +``` + +--- + +## When to Use Each Feature + +| Feature | Use When | Skip When | +|---------|----------|----------| +| **BuildKit** | Always (it's now default) | Legacy Docker versions | +| **Multi-stage builds** | Compiled languages, build tools needed | Simple scripts, static content | +| **Health checks** | Web services, microservices | Batch jobs, CLI tools | +| **Init process** | Long-running services | Single-process containers | +| **Build secrets** | Private registries, paid packages | Public dependencies only | + +--- + +## Common Mistakes + +### 1. Cache Mounts Without BuildKit Syntax + +```dockerfile +# This fails silently +FROM node:22-alpine +RUN --mount=type=cache,target=/root/.npm npm install +``` + +**Fix:** Add syntax directive: +```dockerfile +# syntax=docker/dockerfile:1 +FROM node:22-alpine +RUN --mount=type=cache,target=/root/.npm npm install +``` + +### 2. Health Checks That Never Pass + +```dockerfile +# Wrong: checks before app starts listening +HEALTHCHECK --interval=10s --start-period=5s \\ + CMD curl -f http://localhost:3000/health +``` + +**Fix:** Give adequate start period: +```dockerfile +HEALTHCHECK --interval=10s --start-period=40s \\ + CMD curl -f http://localhost:3000/health +``` + +### 3. Copying Secrets Before Multi-Stage + +```dockerfile +# Leaked in builder stage layers +FROM node:22-alpine AS builder +COPY .npmrc ./ +RUN npm install +``` + +**Fix:** Use secret mounts: +```dockerfile +FROM node:22-alpine AS builder +RUN --mount=type=secret,id=npmrc,target=/root/.npmrc \\ + npm install +``` + +--- + +## Next Steps + +Start with the feature that addresses your biggest pain point: + +**Slow builds?** → Implement BuildKit cache mounts +**Large images?** → Add multi-stage builds +**Deployment failures?** → Add health checks +**Graceful shutdown issues?** → Use init process +**Security concerns?** → Switch to build secrets + +Then progressively adopt the others. The combined effect is greater than the sum of the parts. A well-optimized Dockerfile using all five features builds faster, produces smaller images, runs more reliably, and maintains better security than basic approaches. + +The Docker documentation has detailed guides for each feature. The BuildKit documentation in particular covers many additional capabilities beyond what we've covered here. Experiment with these features in development first, measure the impact, and then roll them out to production. diff --git a/public/images/posts/advanced-docker-features.png b/public/images/posts/advanced-docker-features.png new file mode 100644 index 0000000000000000000000000000000000000000..0454721861cf9ff8236b39d9cf33a1a0cd49bc1c GIT binary patch literal 34497 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�jH3K8#fev>ot?3ic-&z(xOu)@zt5!l>O55`Zf(G*D+ zjU^;VQtV4{ber4(MZfX;ZDcy307?JRC&%Xe;>{w<@$izLtT+3px0ghMoKMWIF1qDT zbAQ$ksFk>^!!Nk-X%S!NKe#GY1IzdkoBPYx^X~Wg&kIixjJXZ|{D|8Y9R4C=ZpQSu z+~OOJZ!e$Gzfl)Civ!D>&Jts-TYCrYBaUC>Snph&^1U8=FgRid>csksVe^oDIELU_ z@W{_ic?>a4pkLKTYu%Up_b};%A-sFEJEiv&^cAI|$T^@@;noclP6Ega?|`T#LUDgt zQP;4p;B}{(bmlZ|>)h@-$Jz!`f9@!p*V<9^4eo(gWm#k`sc|~1C)i>Th(ZIE4oim=% z;lmV%;Mm2iVR3xz>w^Qy_Z?_kiZHW*@O!)fYSxNh)=w5p;ASr6qqpX|OR&#)$aG)1uXL;l#heV^&q z#0RVzR#6jigm^hn>iMK#ftXod#5|W5DffPBVhQWQDJi-vg7Uh}G26GrW|Mz4r-aK@ z{`;VY1RX|bHkf~Rzpe5^*)lS6;`VEmFfoxt(r4pzgF*QyBANk#N^e|q>v+5))o`2` zfyG`+O;aihikg@vPrSxhI_Tn}oG^w+mldZMSP{5M{5?GHNLb9@9VLb*?wI?>IL6v? zRlvDOUvxS}i(>%3hcB>59_@k%k({V^`6;LwyNB3m9p||G+O}0rmm7o+uoK2

KZ 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 literal 0 HcmV?d00001 diff --git a/public/images/posts/advanced-docker-features.svg b/public/images/posts/advanced-docker-features.svg new file mode 100644 index 00000000..346dbb0e --- /dev/null +++ b/public/images/posts/advanced-docker-features.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + DOCKER + + + 5 Advanced Docker Features +Worth Knowing + + + DevOps Daily + \ No newline at end of file