Dockerfile Optimizer
Analyze Dockerfiles across four dimensions and produce prioritized, actionable optimizations with estimated impact.
Workflow
Locate and read the Dockerfile(s) Search for Dockerfile, Dockerfile.*, or *.dockerfile in the project. Read all found files. Also check for .dockerignore and docker-compose.yml for context.
Pass 1 — Image Size Analysis Check for:
- Using slim/alpine/distroless base images where appropriate
- Combining RUN commands to reduce layers
- Cleaning package manager caches (apt clean, apk --no-cache, pip --no-cache-dir)
- Multi-stage build usage to exclude build dependencies
- Unnecessary files copied into the image (check .dockerignore)
- Using COPY instead of ADD (ADD has implicit tar extraction)
- Installing only production dependencies (npm ci --omit=dev, pip install --no-dev) Score: 1-10. Estimate total size reduction in MB/GB.
Pass 2 — Layer Caching Analysis Check for:
- Ordering instructions from least to most frequently changing
- Separate dependency install step before COPY . .
- Using BuildKit cache mounts for package managers
- Avoiding COPY . . before dependency installation
- Using .dockerignore to prevent cache invalidation Score: 1-10. Estimate rebuild time improvement.
Pass 3 — Security Hardening Check for:
- Running as non-root user (USER directive)
- Using specific image tags, not :latest
- No secrets in ENV or ARG that leak into final image
- No unnecessary ports exposed
- Using read-only filesystem where possible
- Scanning for known CVEs in base image
- Dropping capabilities (CAP_DROP ALL)
- Using HEALTHCHECK Score: 1-10. List specific vulnerabilities found.
Pass 4 — Build Speed Check for:
- BuildKit syntax enabled (# syntax=docker/dockerfile:1)
- Parallel build stages where possible
- Using --mount=type=cache for apt/pip/npm caches
- Avoiding unnecessary .dockerignore exclusions that force full rebuilds
- Using ADD for remote URLs instead of RUN curl Score: 1-10. Estimate build time savings.
Generate the report Format as a structured report:
Optimization Report
Dimension Score Impact Image Size 7/10 -340MB Layer Caching 5/10 -45s Security 6/10 3 issues Build Speed 8/10 -12s Then list each optimization as:
- Priority: High/Medium/Low
- Issue: What's wrong
- Fix: What to change (with code diff)
- Impact: Estimated benefit
Write the optimized Dockerfile If requested, write the optimized version with comments explaining each change.
Rules
- Always explain WHY each change matters, not just what to change
- Show the diff (before → after) for every optimization
- Estimate size/time savings conservatively
- Don't change the application's runtime behavior — only optimize infrastructure
- If the Dockerfile is already well-optimized, say so honestly
- Always check if the project uses docker-compose before changing port mappings
- Preserve the original EXPOSE ports and CMD/ENTRYPOINT
- If multi-stage is recommended, ensure the final stage is clean (no build tools)
Example Optimized Multi-Stage Pattern
# syntax=docker/dockerfile:1
FROM node:20-alpine AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN --mount=type=cache,target=/root/.npm \\
npm ci --omit=dev
FROM node:20-alpine AS builder
WORKDIR /app
COPY package.json package-lock.json ./
RUN --mount=type=cache,target=/root/.npm \\
npm ci
COPY . .
RUN npm run build
FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
RUN addgroup --system --gid 1001 nodejs && \\
adduser --system --uid 1001 appuser
COPY --from=deps /app/node_modules ./node_modules
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/package.json ./
USER appuser
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=3s \\
CMD wget -q --spider http://localhost:3000/health || exit 1
CMD ["node", "dist/server.js"]