Dockerfile Generator
This skill provides a comprehensive workflow for generating production-ready Dockerfiles with security, optimization, and best practices built-in. Generates multi-stage builds, security-hardened configurations, and optimized layer structures with automatic validation and iterative error fixing.
Overview
Dockerfile Generator
Overview
This skill provides a comprehensive workflow for generating production-ready Dockerfiles with security, optimization, and best practices built-in. Generates multi-stage builds, security-hardened configurations, and optimized layer structures with automatic validation and iterative error fixing.
Key Features:
- Multi-stage builds for optimal image size (50-85% reduction)
- Security hardening (non-root users, minimal base images, no secrets)
- Layer caching optimization for faster builds
- Language-specific templates (Node.js, Python, Go, Java)
- Automatic .dockerignore generation
- Integration with
dockerfile-validatorfor validation - Iterative validation and error fixing (minimum 1 iteration if errors found)
- Local references plus docs lookup fallback chain for framework-specific patterns
When to Use This Skill
Invoke this skill when:
- Creating new Dockerfiles from scratch
- Containerizing applications (Node.js, Python, Go, Java, or other languages)
- Implementing multi-stage builds for size optimization
- Converting existing Dockerfiles to best practices
- Generating production-ready container configurations
- Optimizing Docker builds for security and performance
- The user asks to "create", "generate", "build", or "write" a Dockerfile
- Implementing containerization for microservices
- Setting up CI/CD pipeline container builds
Trigger Phrases
Use this skill immediately when the request contains phrasing like:
- "Generate a production Dockerfile for my app"
- "Create a multi-stage Dockerfile for <language/framework>"
- "Containerize this service with security best practices"
- "Optimize this Dockerfile for size and build speed"
- "Write Dockerfile and .dockerignore for deployment"
Do NOT Use This Skill For
- Validating existing Dockerfiles (use
dockerfile-validatorinstead) - Building or running containers (use docker build/run commands)
- Debugging running containers (use docker logs, docker exec)
- Managing Docker images or registries
Deterministic Execution Model
Run these stages in order, and do not skip a stage unless the skip reason is reported in the final output.
- Gather requirements (language, runtime version, entrypoint, exposed port, package manager, health endpoint).
- Load references (local reference files first; external docs only when local references are insufficient).
- Generate Dockerfile and
.dockerignore. - Validate with
dockerfile-validatoror fallback local tools. - Iterate fixes until stop condition is met.
- Publish final artifacts plus validation/audit report.
Stop conditions for stage 5:
- Stop when there are zero validation errors and no unapproved warnings.
- Stop after 3 iterations maximum, then emit an intentional-deviation report for unresolved findings.
Reference Path Map
Consult these files directly by path as needed:
references/security_best_practices.mdfor non-root users, secret handling, base image hardening, vulnerability scanning.references/optimization_patterns.mdfor multi-stage strategy, cache optimization, layer reduction, BuildKit cache mounts.references/language_specific_guides.mdfor language/framework runtime and package-manager patterns.references/multistage_builds.mdfor advanced stage-splitting and artifact-copy patterns.
Dockerfile Generation Workflow
Follow this workflow when generating Dockerfiles. Adapt based on user needs:
Stage 1: Gather Requirements
Objective: Understand what needs to be containerized and gather all necessary information.
Information to Collect:
-
Application Details:
- Programming language and version (Node.js 18/20, Python 3.11/3.12, Go 1.21+, Java 17/21, etc.)
- Application type (web server, API, CLI tool, batch job, etc.)
- Framework (Express, FastAPI, Spring Boot, etc.)
- Entry point (main file, command to run)
-
Dependencies:
- Package manager (npm/yarn/pnpm, pip/poetry, go mod, maven/gradle)
- System dependencies (build tools, libraries, etc.)
- Build-time vs runtime dependencies
-
Application Configuration:
- Port(s) to expose
- Environment variables needed
- Configuration files
- Health check endpoint (for web services)
- Volume mounts (if any)
-
Build Requirements:
- Build commands
- Test commands (optional)
- Compilation needs (for compiled languages)
- Static asset generation
-
Production Requirements:
- Expected image size constraints
- Security requirements
- Scaling needs
- Resource constraints (CPU, memory)
Use AskUserQuestion if information is missing or unclear.
Example Questions:
- What programming language and version is your application using?
- What is the main entry point to run your application?
- Does your application expose any ports? If so, which ones?
- Do you need any system dependencies beyond the base language runtime?
- Does your application need a health check endpoint?
Stage 2: Framework/Library Documentation Lookup (if needed)
Objective: Research framework-specific containerization patterns and best practices.
When to Perform This Stage:
- User mentions a specific framework (Next.js, Django, FastAPI, Spring Boot, etc.)
- Application has complex build requirements
- Need guidance on framework-specific optimization
Research Process (strict fallback chain):
-
Read local references first (required):
references/security_best_practices.mdreferences/optimization_patterns.mdreferences/language_specific_guides.md
-
Use Context7 docs lookup when local references are insufficient (preferred external source):
Use mcp__context7__resolve-library-id with the framework name Then use mcp__context7__query-docs with query: "docker deployment production build" -
Use web search only if Context7 is unavailable or missing needed details:
"<framework>" "<version>" dockerfile production deployment best practices -
If external lookup is unavailable (offline/tooling limits):
- Continue with local references and language templates in this file.
- State assumptions explicitly in the output.
- Mark the lookup limitation in the final report.
-
Extract only actionable data:
- Recommended base image + version policy
- Build optimization techniques
- Required runtime environment variables
- Production vs development differences
- Security requirements specific to the framework
Stage 3: Generate Dockerfile
Objective: Create a production-ready, multi-stage Dockerfile following best practices.
Core Principles:
-
Multi-Stage Builds (REQUIRED for compiled languages, RECOMMENDED for all):
- Separate build stage from runtime stage
- Keep build tools out of final image
- Copy only necessary artifacts
- Results in 50-85% smaller images
-
Security Hardening (REQUIRED):
- Use specific version tags (NEVER use :latest)
- Run as non-root user (create dedicated user)
- Use minimal base images (alpine, distroless)
- No hardcoded secrets
- Scan base images for vulnerabilities
-
Layer Optimization (REQUIRED):
- Order instructions from least to most frequently changing
- Copy dependency files before application code
- Combine related RUN commands with &&
- Clean up package manager caches in same layer
- Leverage build cache effectively
-
Production Readiness (REQUIRED):
- Add HEALTHCHECK for services
- Use exec form for ENTRYPOINT/CMD
- Set WORKDIR to absolute paths
- Document exposed ports with EXPOSE
Language-Specific Templates:
Node.js Multi-Stage Dockerfile
Build-stage dependency rule: If the application has a build step (TypeScript, Vite, Webpack, etc.), install all dependencies in the builder stage (omit
--only=production) and prune dev deps after the build. Using--only=productionbefore a build step will causenpm run buildto fail because dev tools are not installed.
# syntax=docker/dockerfile:1
# Build stage — installs all deps so build tools (tsc, vite, etc.) are available,
# then prunes dev deps so the production stage only ships what is needed at runtime.
FROM node:20-alpine AS builder
WORKDIR /app
# Copy dependency files for caching
COPY package*.json ./
# Install ALL dependencies (including devDependencies required by the build step)
RUN npm ci && \\
npm cache clean --force
# Copy application code
COPY . .
# Build application and prune dev dependencies
RUN npm run build && \\
npm prune --production
# Production stage
FROM node:20-alpine AS production
WORKDIR /app
# Set production environment
ENV NODE_ENV=production
# Create non-root user
RUN addgroup -g 1001 -S nodejs && \\
adduser -S nodejs -u 1001
# Copy pruned node_modules and built application from builder
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
# 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)})"
# Start application
CMD ["node", "index.js"]
Simple app (no build step): If there is no compilation or bundling, install only production deps in the builder stage and copy source from the host context:
RUN npm ci --only=production && npm cache clean --force ... COPY --from=builder --chown=nodejs:nodejs /app/node_modules ./node_modules COPY --chown=nodejs:nodejs . .
Python Multi-Stage Dockerfile
# syntax=docker/dockerfile:1
# Build stage
FROM python:3.12-slim AS builder
WORKDIR /app
# Install build dependencies
# hadolint ignore=DL3008
RUN apt-get update && apt-get install -y --no-install-recommends \\
gcc \\
&& rm -rf /var/lib/apt/lists/*
# Copy dependency files
COPY requirements.txt .
# Install Python dependencies
RUN pip install --no-cache-dir --user -r requirements.txt
# Production stage
FROM python:3.12-slim AS production
WORKDIR /app
# Create non-root user
RUN useradd -m -u 1001 appuser
# Copy dependencies from builder
COPY --from=builder /root/.local /home/appuser/.local
# Copy application code
COPY --chown=appuser:appuser . .
# Update PATH and set Python production env vars
# PYTHONUNBUFFERED=1 ensures stdout/stderr are flushed immediately (essential for container logs)
# PYTHONDONTWRITEBYTECODE=1 prevents writing .pyc files to disk
ENV PATH=/home/appuser/.local/bin:$PATH \\
PYTHONUNBUFFERED=1 \\
PYTHONDONTWRITEBYTECODE=1
# Switch to non-root user
USER appuser
# Expose port
EXPOSE 8000
# Health check (adjust endpoint as needed)
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \\
CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health').read()" || exit 1
# Start application
CMD ["python", "app.py"]
Go Multi-Stage Dockerfile
# syntax=docker/dockerfile:1
# Build stage
FROM golang:1.21-alpine AS builder
WORKDIR /app
# Copy go mod files
COPY go.mod go.sum ./
RUN go mod download
# Copy source code
COPY . .
# Build the application
RUN CGO_ENABLED=0 GOOS=linux go build -a -ldflags="-s -w" -o main .
# Production stage (using distroless for minimal image)
# gcr.io/distroless/static-debian12 IS a specific tag; hadolint DL3006 is a
# false positive for non-Docker-Hub registries.
# hadolint ignore=DL3006
FROM gcr.io/distroless/static-debian12 AS production
WORKDIR /
# Copy binary from builder
COPY --from=builder /app/main /main
# Expose port
EXPOSE 8080
# HEALTHCHECK is not supported in distroless images (no shell available)
# Switch to non-root user (distroless runs as nonroot by default)
USER nonroot:nonroot
# Start application
ENTRYPOINT ["/main"]
Java Multi-Stage Dockerfile
# syntax=docker/dockerfile:1
# Build stage
FROM eclipse-temurin:21-jdk-jammy AS builder
WORKDIR /app
# Copy Maven wrapper and pom.xml
COPY mvnw pom.xml ./
COPY .mvn .mvn
# Download dependencies (cached layer)
RUN ./mvnw dependency:go-offline
# Copy source code
COPY src ./src
# Build application
RUN ./mvnw clean package -DskipTests && \\
mv target/*.jar target/app.jar
# Production stage (using JRE instead of JDK)
FROM eclipse-temurin:21-jre-jammy AS production
WORKDIR /app
# Install healthcheck dependency and create non-root user
# hadolint ignore=DL3008
RUN apt-get update && apt-get install -y --no-install-recommends curl && \\
rm -rf /var/lib/apt/lists/* && \\
useradd -m -u 1001 appuser
# Copy JAR from builder
COPY --from=builder --chown=appuser:appuser /app/target/app.jar ./app.jar
# Switch to non-root user
USER appuser
# Expose port
EXPOSE 8080
# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3 \\
CMD curl -f http://localhost:8080/actuator/health || exit 1
# Start application
ENTRYPOINT ["java", "-jar", "app.jar"]
Selection Logic:
- Node.js: Use for JavaScript/TypeScript applications
- Python: Use for Python applications (web, API, scripts)
- Go: Use for Go applications (excellent for minimal images)
- Java: Use for Spring Boot, Quarkus, or other Java frameworks
- Generic: Create custom Dockerfile for other languages
Always Include:
- Syntax directive:
# syntax=docker/dockerfile:1 - Multi-stage build (build + production stages)
- Non-root user creation and usage
- HEALTHCHECK for services (if applicable)
- Proper WORKDIR settings
- EXPOSE for documented ports
- Clean package manager caches
- exec form for CMD/ENTRYPOINT
Stage 4: Generate .dockerignore
Objective: Create comprehensive .dockerignore to reduce build context and prevent secret leaks.
Always create .dockerignore with generated Dockerfile.
Standard .dockerignore Template:
# Git
.git
.gitignore
.gitattributes
# CI/CD
.github
.gitlab-ci.yml
.travis.yml
.circleci
# Documentation
README.md
CHANGELOG.md
CONTRIBUTING.md
LICENSE
*.md
docs/
# Docker
Dockerfile*
docker-compose*.yml
.dockerignore
# Environment
.env
.env.*
*.local
# Logs
logs/
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Dependencies (language-specific - add as needed)
node_modules/
__pycache__/
*.pyc
*.pyo
*.pyd
.Python
venv/
.venv/
target/
*.class
# IDE
.vscode/
.idea/
*.swp
*.swo
*~
.DS_Store
# Testing
coverage/
.coverage
*.cover
.pytest_cache/
.tox/
test-results/
# Build artifacts
dist/
build/
*.egg-info/
Customize based on language:
- Node.js: Add
node_modules/,npm-debug.log,yarn-error.log - Python: Add
__pycache__/,*.pyc,.venv/,.pytest_cache/ - Go: Add
vendor/,*.exe,*.test