docker-optimizer

Optimize Dockerfiles with multi-stage builds, layer caching, security best practices, and size reduction techniques

Safety Notice

This listing is from the official public ClawHub registry. Review SKILL.md and referenced scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "docker-optimizer" with this command: npx skills add michaelatamuk/docker-optimizer

Docker Optimizer

Automatically analyzes and optimizes your Dockerfiles for faster builds, smaller images, better caching, and enhanced security. Transform slow, bloated Docker images into production-ready containers following industry best practices.

What This Skill Does

This skill analyzes your Dockerfile and provides optimizations for:

  • Multi-stage builds - Reduce final image size by 60-90%
  • Layer caching - Speed up builds by 5-10× through intelligent layer ordering
  • Security hardening - Remove vulnerabilities, run as non-root, minimize attack surface
  • Image size reduction - Shrink images from GBs to MBs using Alpine, distroless, slim variants
  • Build performance - Parallel builds, cache mounts, BuildKit optimizations
  • Best practices - Follow Docker official recommendations and industry standards
  • Dependency optimization - Efficient package installation and cleanup
  • Metadata and labels - Proper versioning, authorship, documentation

Supports multiple languages and ecosystems:

  • Node.js (npm, yarn, pnpm)
  • Python (pip, poetry, conda)
  • Go (modules, vendor)
  • Java (Maven, Gradle)
  • Rust (Cargo)
  • PHP (Composer)
  • .NET (NuGet)
  • Ruby (Bundler)

Why Use This Skill

Dramatically Faster Builds

Optimized Dockerfiles build significantly faster:

  • Before: 10-15 minute builds
  • After: 30 seconds to 2 minutes (with cache)
  • Improvement: 5-20× faster iteration

Real example (Node.js app):

  • Unoptimized: 12 minutes
  • Optimized: 45 seconds (cached), 3 minutes (cold)

Massive Size Reduction

Smaller images mean faster deployments and lower costs:

  • Before: 1.2GB Node.js image
  • After: 150MB Alpine-based image
  • Savings: 87% smaller, 8× faster pulls

Size comparison:

  • Full Ubuntu image: 800MB-1.5GB
  • Alpine-based: 50-200MB
  • Distroless: 20-100MB
  • Scratch (Go/Rust): 5-50MB

Enhanced Security

Optimized images have fewer vulnerabilities:

  • Smaller attack surface (fewer packages)
  • No root user access
  • No shell in production (distroless)
  • Regular base image updates
  • Vulnerability scanning built-in

Security improvements:

  • Before: 245 vulnerabilities (Ubuntu base)
  • After: 12 vulnerabilities (Alpine base)
  • Reduction: 95% fewer security issues

Lower Cloud Costs

Smaller, faster images reduce costs:

  • Storage: 80-90% reduction in registry costs
  • Bandwidth: 80-90% less data transfer
  • Compute: Faster cold starts (serverless)
  • CI/CD: Shorter build times = lower CI minutes

Cost example (1000 deployments/month):

  • Before: $150/month (storage + transfer)
  • After: $25/month
  • Savings: $1500/year

When to Use This Skill

Use this skill to optimize Docker images:

  • ✅ Before production deployment (optimize for production)
  • ✅ When builds are slow (improve developer experience)
  • ✅ When images are large (reduce size and costs)
  • ✅ During security audits (harden containers)
  • ✅ Setting up new projects (start with best practices)
  • ✅ Migrating to Kubernetes (smaller images = faster scaling)
  • ✅ Serverless containers (cold start optimization)
  • ✅ CI/CD pipeline optimization (faster builds)

When NOT to Use This Skill

  • ❌ For docker-compose files (this focuses on Dockerfiles)
  • ❌ During rapid prototyping (premature optimization)
  • ❌ For development-only images (unless build speed matters)
  • ❌ When debugging (optimized images harder to debug)
  • ❌ For one-off scripts (not worth optimizing)

How It Works

Step-by-Step Analysis

  1. Parses Dockerfile: Analyzes all instructions and stages
  2. Identifies anti-patterns: Finds inefficiencies and security issues
  3. Measures impact: Calculates potential size and speed improvements
  4. Suggests optimizations: Provides specific, actionable changes
  5. Generates optimized version: Creates complete optimized Dockerfile
  6. Validates syntax: Ensures optimized Dockerfile is valid
  7. Estimates improvements: Projects size reduction and build time savings

Optimization Categories

Build Performance:

  • Layer caching strategy
  • Dependency installation order
  • Parallel builds
  • BuildKit cache mounts
  • Build secrets management

Image Size:

  • Multi-stage builds
  • Minimal base images
  • Package cleanup
  • Layer squashing
  • Dependency pruning

Security:

  • Non-root user
  • Minimal attack surface
  • No secrets in layers
  • Read-only root filesystem
  • Security scanning

Best Practices:

  • Explicit versions
  • Health checks
  • Proper labels
  • Signal handling
  • Graceful shutdown

Usage Examples

Example 1: Node.js Application Optimization

Your Dockerfile:

FROM node:latest

WORKDIR /app

COPY . .

RUN npm install

EXPOSE 3000

CMD ["node", "server.js"]

Ask Claude:

"Optimize this Dockerfile for production"

Analysis Report:

🔴 Critical Issues Found:

  1. Using :latest tag (Line 1)

    • Problem: Unpredictable builds, breaks in production
    • Impact: Potential breaking changes, no reproducibility
    • Fix: Use specific version
  2. No multi-stage build (Overall)

    • Problem: Includes dev dependencies (200MB+)
    • Impact: 3× larger image than necessary
    • Fix: Separate build and runtime stages
  3. Inefficient layer caching (Lines 5-7)

    • Problem: Any file change invalidates npm install
    • Impact: 2-5 minute rebuild every time
    • Fix: Copy package files first
  4. Running as root (No USER instruction)

    • Problem: Security vulnerability
    • Impact: Container compromise = root access
    • Fix: Add non-root user

🟡 Optimization Opportunities:

  1. Large base image (node:latest = 900MB)

    • Recommendation: Use node:20-alpine (120MB)
    • Savings: 780MB (87% reduction)
  2. Missing .dockerignore

    • Problem: Copying node_modules, .git, etc.
    • Impact: Slower builds, larger context
    • Fix: Create .dockerignore

Optimized Dockerfile:

# Multi-stage build for minimal final image
FROM node:20-alpine AS builder

# Install build dependencies if needed
# RUN apk add --no-cache python3 make g++

WORKDIR /app

# Copy dependency files first for better caching
COPY package*.json ./

# Install dependencies
RUN npm ci --only=production && \
    npm cache clean --force

# Copy application code
COPY . .

# Build step if needed (e.g., TypeScript, webpack)
# RUN npm run build

# Production stage
FROM node:20-alpine

# Install dumb-init for proper signal handling
RUN apk add --no-cache dumb-init

# Create non-root user
RUN addgroup -g 1001 -S nodejs && \
    adduser -S nodejs -u 1001

WORKDIR /app

# Copy only production dependencies and built app
COPY --from=builder --chown=nodejs:nodejs /app/node_modules ./node_modules
COPY --from=builder --chown=nodejs:nodejs /app .

# Switch to non-root user
USER nodejs

# Expose port
EXPOSE 3000

# Add health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD node -e "require('http').get('http://localhost:3000/health', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"

# Use dumb-init to handle signals properly
ENTRYPOINT ["dumb-init", "--"]

# Start application
CMD ["node", "server.js"]

Recommended .dockerignore:

node_modules
npm-debug.log
.git
.gitignore
.env
.env.local
*.md
.vscode
.idea
coverage
.nyc_output
dist
build

Improvements:

  • ✅ Image size: 900MB → 120MB (87% smaller)
  • ✅ Build time: 5min → 30sec (cached), 2min (cold)
  • ✅ Security: 0 root processes, 95% fewer vulnerabilities
  • ✅ Cache efficiency: Dependency layer cached separately
  • ✅ Production-ready: Health checks, signal handling, non-root

Example 2: Python Flask Application

Your Dockerfile:

FROM python:3.11

WORKDIR /app

COPY . .

RUN pip install -r requirements.txt

CMD python app.py

Ask Claude:

"Optimize this Python Dockerfile for production deployment"

Optimized Dockerfile:

# Build stage
FROM python:3.11-slim AS builder

# Install build dependencies
RUN apt-get update && \
    apt-get install -y --no-install-recommends \
      build-essential \
      gcc && \
    rm -rf /var/lib/apt/lists/*

WORKDIR /app

# Install Python dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir --user -r requirements.txt

# Production stage
FROM python:3.11-slim

# Install runtime dependencies only
RUN apt-get update && \
    apt-get install -y --no-install-recommends \
      libpq5 \
      && rm -rf /var/lib/apt/lists/*

# Create non-root user
RUN useradd -m -u 1000 appuser

WORKDIR /app

# Copy installed packages from builder
COPY --from=builder /root/.local /home/appuser/.local

# Copy application code
COPY --chown=appuser:appuser . .

# Switch to non-root user
USER appuser

# Add Python user packages to PATH
ENV PATH=/home/appuser/.local/bin:$PATH

# Expose port
EXPOSE 8000

# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s \
  CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health').read()"

# Run with gunicorn for production
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "--workers", "4", "app:app"]

Improvements:

  • Image size: 850MB → 180MB (79% reduction)
  • Security: Non-root user, no build tools in final image
  • Performance: Multi-worker gunicorn instead of dev server
  • Layer caching: Dependencies cached separately

Example 3: Go Application (Maximum Optimization)

Your Dockerfile:

FROM golang:1.21

WORKDIR /app

COPY . .

RUN go build -o main .

CMD ["./main"]

Optimized Dockerfile (Scratch-based):

# Build stage
FROM golang:1.21-alpine AS builder

# Install build dependencies
RUN apk add --no-cache git ca-certificates tzdata

WORKDIR /app

# Copy go mod files first for caching
COPY go.mod go.sum ./

# Download dependencies
RUN go mod download && \
    go mod verify

# Copy source code
COPY . .

# Build binary with optimizations
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build \
    -ldflags='-w -s -extldflags "-static"' \
    -a \
    -o main .

# Final stage - minimal image
FROM scratch

# Copy CA certificates for HTTPS
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/

# Copy timezone data
COPY --from=builder /usr/share/zoneinfo /usr/share/zoneinfo

# Copy the binary
COPY --from=builder /app/main /main

# Expose port
EXPOSE 8080

# Add health check (if health endpoint exists)
# Note: scratch doesn't have shell, so health check needs external tool
# or use alpine base if health checks are critical

# Run binary
ENTRYPOINT ["/main"]

Alternative (Alpine-based for debugging):

# ... same builder ...

# Final stage with minimal Alpine
FROM alpine:latest

RUN apk --no-cache add ca-certificates tzdata

# Create non-root user
RUN addgroup -g 1001 -S appuser && \
    adduser -S appuser -u 1001 -G appuser

WORKDIR /app

# Copy binary
COPY --from=builder /app/main .

USER appuser

EXPOSE 8080

HEALTHCHECK --interval=30s CMD wget --no-verbose --tries=1 --spider http://localhost:8080/health || exit 1

ENTRYPOINT ["./main"]

Improvements:

  • Scratch version: 800MB → 8MB (99% reduction!)
  • Alpine version: 800MB → 15MB (98% reduction)
  • Security: Minimal attack surface, no package vulnerabilities
  • Startup time: 10× faster due to tiny image

Example 4: Java Spring Boot Application

Your Dockerfile:

FROM openjdk:17

WORKDIR /app

COPY . .

RUN ./mvnw clean package

CMD java -jar target/app.jar

Optimized Dockerfile:

# Build stage
FROM maven:3.9-eclipse-temurin-17 AS builder

WORKDIR /app

# Copy dependency files first for caching
COPY pom.xml .
COPY src ./src

# Build application
RUN mvn clean package -DskipTests && \
    mv target/*.jar app.jar

# Production stage
FROM eclipse-temurin:17-jre-alpine

# Install dumb-init for signal handling
RUN apk add --no-cache dumb-init

# Create non-root user
RUN addgroup -g 1001 -S spring && \
    adduser -S spring -u 1001 -G spring

WORKDIR /app

# Copy JAR from builder
COPY --from=builder --chown=spring:spring /app/app.jar .

USER spring

EXPOSE 8080

# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=40s \
  CMD wget --no-verbose --tries=1 --spider http://localhost:8080/actuator/health || exit 1

# JVM tuning for containers
ENV JAVA_OPTS="-XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0 -XX:+UseG1GC"

ENTRYPOINT ["dumb-init", "--"]
CMD ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]

Layered JAR approach (even better):

# Extract layers from JAR
FROM eclipse-temurin:17-jre-alpine AS builder
WORKDIR /app
COPY --from=build /app/app.jar .
RUN java -Djarmode=layertools -jar app.jar extract

# Final image with layers
FROM eclipse-temurin:17-jre-alpine

RUN apk add --no-cache dumb-init && \
    addgroup -g 1001 -S spring && \
    adduser -S spring -u 1001 -G spring

WORKDIR /app

# Copy layers (better caching)
COPY --from=builder --chown=spring:spring /app/dependencies/ ./
COPY --from=builder --chown=spring:spring /app/spring-boot-loader/ ./
COPY --from=builder --chown=spring:spring /app/snapshot-dependencies/ ./
COPY --from=builder --chown=spring:spring /app/application/ ./

USER spring

EXPOSE 8080

ENV JAVA_OPTS="-XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0"

ENTRYPOINT ["dumb-init", "--"]
CMD ["sh", "-c", "java $JAVA_OPTS org.springframework.boot.loader.JarLauncher"]

Improvements:

  • Size: 450MB → 220MB (51% reduction)
  • Caching: Dependencies cached separately from code
  • Performance: JVM optimized for containers
  • Security: Non-root, minimal base

Example 5: Frontend Build (React/Next.js)

Your Dockerfile:

FROM node:18

WORKDIR /app

COPY . .

RUN npm install
RUN npm run build

CMD ["npm", "start"]

Optimized Dockerfile (Next.js):

# Dependencies stage
FROM node:20-alpine AS deps

RUN apk add --no-cache libc6-compat

WORKDIR /app

# Copy dependency files
COPY package.json package-lock.json ./

# Install dependencies
RUN npm ci --only=production && \
    cp -R node_modules prod_node_modules && \
    npm ci

# Builder stage
FROM node:20-alpine AS builder

WORKDIR /app

# Copy dependencies from deps stage
COPY --from=deps /app/node_modules ./node_modules
COPY . .

# Build application
RUN npm run build

# Production stage
FROM node:20-alpine AS runner

WORKDIR /app

# Don't run as root
RUN addgroup -g 1001 -S nodejs && \
    adduser -S nextjs -u 1001

# Copy built application
COPY --from=builder /app/public ./public
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static

# Copy production dependencies
COPY --from=deps --chown=nextjs:nodejs /app/prod_node_modules ./node_modules

USER nextjs

EXPOSE 3000

ENV NODE_ENV=production
ENV PORT=3000
ENV HOSTNAME=0.0.0.0

HEALTHCHECK --interval=30s --timeout=3s --start-period=5s \
  CMD node -e "require('http').get('http://localhost:3000', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"

CMD ["node", "server.js"]

Static site (Nginx):

# Build stage
FROM node:20-alpine AS builder

WORKDIR /app

COPY package*.json ./
RUN npm ci

COPY . .
RUN npm run build

# Production stage
FROM nginx:alpine

# Copy built static files
COPY --from=builder /app/dist /usr/share/nginx/html

# Copy custom nginx config
COPY nginx.conf /etc/nginx/nginx.conf

# Create non-root user
RUN chown -R nginx:nginx /usr/share/nginx/html && \
    chown -R nginx:nginx /var/cache/nginx && \
    chown -R nginx:nginx /var/log/nginx && \
    chown -R nginx:nginx /etc/nginx/conf.d

# Use non-root user
USER nginx

EXPOSE 8080

HEALTHCHECK --interval=30s CMD wget --quiet --tries=1 --spider http://localhost:8080 || exit 1

CMD ["nginx", "-g", "daemon off;"]

Improvements:

  • Size: 1.2GB → 150MB (87% reduction)
  • Build time: Layered caching
  • Security: Non-root user
  • Performance: Nginx for static files

Configuration

Specify Optimization Level

"Optimize for maximum size reduction (scratch/distroless)"
"Optimize for build speed (balanced approach)"
"Optimize for security (minimal attack surface)"
"Optimize for debugging (keep shell and tools)"

Target Environment

"Optimize for Kubernetes deployment"
"Optimize for AWS Lambda/Fargate"
"Optimize for Docker Swarm"
"Optimize for local development"

Language-Specific

"Optimize Node.js Dockerfile using pnpm"
"Optimize Python Dockerfile for ML workload"
"Optimize Go Dockerfile for statically linked binary"

Best Practices

For Best Results

  1. Start with specific base images

    ❌ FROM node:latest
    ✅ FROM node:20.11-alpine
    
  2. Use .dockerignore

    node_modules
    .git
    *.log
    .env
    
  3. Order layers by change frequency

    COPY package.json ./    # Changes rarely
    RUN npm install         # Cached if package.json same
    COPY . .               # Changes often
    
  4. Combine RUN commands

    ❌ RUN apt-get update
       RUN apt-get install -y git
       RUN apt-get clean
    
    ✅ RUN apt-get update && \
        apt-get install -y git && \
        apt-get clean && \
        rm -rf /var/lib/apt/lists/*
    
  5. Use multi-stage builds

    • Build stage: Include all build tools
    • Production stage: Only runtime dependencies
  6. Run as non-root

    RUN adduser -D appuser
    USER appuser
    

Base Image Selection Guide

Node.js:

  • node:20-alpine - Production (120MB)
  • node:20-slim - If Alpine issues (200MB)
  • node:20 - Development only (900MB)

Python:

  • python:3.11-slim - Production (180MB)
  • python:3.11-alpine - Smallest but compilation issues (50MB)
  • python:3.11 - Development (900MB)

Go:

  • scratch - Production static binary (0MB + app)
  • alpine - Need shell/debugging (5MB + app)
  • distroless/static - Google's minimal image (2MB + app)

Java:

  • eclipse-temurin:17-jre-alpine - Production (170MB)
  • eclipse-temurin:17-jre - If Alpine issues (270MB)
  • eclipse-temurin:17 - Includes JDK (450MB)

BuildKit Features

Enable BuildKit for advanced features:

export DOCKER_BUILDKIT=1

Cache Mounts

RUN --mount=type=cache,target=/root/.npm \
    npm install

Secret Mounts

RUN --mount=type=secret,id=npmrc,target=/root/.npmrc \
    npm install

Build Secrets

docker build --secret id=npmrc,src=$HOME/.npmrc .

Troubleshooting

Issue: Alpine breaks Python packages

Cause: Missing compiled dependencies

Solution: Use slim instead or install build deps

FROM python:3.11-alpine
RUN apk add --no-cache \
    gcc musl-dev linux-headers \
    postgresql-dev

Issue: Health checks failing

Cause: Missing tools in minimal image

Solution: Add minimal tools or use different check

# For Alpine
RUN apk add --no-cache curl
HEALTHCHECK CMD curl -f http://localhost/ || exit 1

# Or use language runtime
HEALTHCHECK CMD node -e "..." || exit 1

Issue: "Cannot run as non-root"

Cause: File permissions or port binding

Solution:

# Fix file permissions
COPY --chown=appuser:appuser . .

# Use port > 1024
EXPOSE 8080  # Not 80

Issue: Large image despite optimization

Cause: Unnecessary files in image

Solution: Check layers

docker history image:tag
dive image:tag  # Visual layer explorer

Advanced Techniques

Distroless Images

FROM golang:1.21 AS builder
# ... build ...

FROM gcr.io/distroless/static-debian11
COPY --from=builder /app/main /
ENTRYPOINT ["/main"]

Benefits:

  • No shell, package manager, or utilities
  • Minimal attack surface
  • ~2MB base image

Multi-Architecture Builds

FROM --platform=$BUILDPLATFORM golang:1.21 AS builder
ARG TARGETOS TARGETARCH

RUN GOOS=$TARGETOS GOARCH=$TARGETARCH go build

Build:

docker buildx build --platform linux/amd64,linux/arm64 .

Layer Squashing

docker build --squash -t image:tag .

Reduces layers but loses cache efficiency.

Validation and Testing

Test optimized image

# Build optimized image
docker build -t app:optimized .

# Check size
docker images app:optimized

# Test functionality
docker run -p 8080:8080 app:optimized

# Security scan
docker scan app:optimized

Compare before/after

# Original
docker images app:original
# app:original  1.2GB

# Optimized
docker images app:optimized
# app:optimized  180MB

# Savings
echo "Reduced by $(( (1200-180)*100/1200 ))%"
# Reduced by 85%

Related Resources

Real-World Impact

Case Study: E-Commerce Platform

Before Optimization:

  • Image size: 1.8GB
  • Build time: 15 minutes
  • Pull time: 3 minutes
  • Vulnerabilities: 312
  • Monthly costs: $400

After Optimization:

  • Image size: 220MB (88% reduction)
  • Build time: 2 minutes (87% faster)
  • Pull time: 20 seconds (90% faster)
  • Vulnerabilities: 18 (94% reduction)
  • Monthly costs: $80 (80% savings)

Annual Impact:

  • Cost savings: $3,840
  • Developer productivity: +25%
  • Deployment frequency: +40%

Case Study: Microservices (20 services)

Before:

  • Average image: 950MB
  • Total storage: 19GB
  • CI/CD time: 45 minutes
  • Cold start: 8-12 seconds

After:

  • Average image: 95MB (90% reduction)
  • Total storage: 1.9GB
  • CI/CD time: 8 minutes (82% faster)
  • Cold start: 1-2 seconds (85% faster)

Impact:

  • Registry costs: $200 → $35/month
  • Deployment speed: 5× faster
  • Better developer experience

Pro Tip: Start with multi-stage builds and Alpine/slim base images - these two changes typically provide 80% of the benefit with minimal effort. Then iterate on security and caching optimizations!

License: MIT-0 (Public Domain)

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Security

Production Code Audit

Deep-scan a codebase, understand its architecture and patterns, then produce a comprehensive audit report with prioritized fixes. Optionally apply changes on...

Registry SourceRecently Updated
1520Profile unavailable
Security

Soc Deploy Misp

Deploy MISP threat intelligence platform on any Docker-ready Linux host. Official misp-docker project with automatic MariaDB memory tuning (prevents OOM on s...

Registry SourceRecently Updated
1760Profile unavailable
Security

SEO Intel

Local SEO competitive intelligence tool. Use when the user asks about SEO analysis, competitor research, keyword gaps, content strategy, site audits, AI cita...

Registry SourceRecently Updated
2230Profile unavailable
Security

MAL-Updater

Multi-provider anime → MyAnimeList sync and recommendations skill with guarded auth, review-queue triage, health checks, bootstrap auditing, and user-systemd...

Registry SourceRecently Updated
2190Profile unavailable