| name | dockerfile-generation |
| description | Use when creating Dockerfiles, optimizing container images, or reviewing Docker configurations. Produces multi-stage, security-hardened builds with proper layer caching. Triggers on 'create Dockerfile', 'dockerize', 'optimize container'. |
| metadata | {"author":"dtsong"} |
Dockerfile Generation Skill
Generate production-ready Dockerfiles through iterative verification.
Scope Constraints
- Read access to codebase for analysis; write access limited to Dockerfile and .dockerignore
- Executes
docker build and docker run for verification only — no deployment or registry push
- Does not modify application source code or dependency files
- Does not configure CI/CD pipelines — delegates to cicd-generation skill
Input Sanitization
- Base image names: alphanumeric, hyphens, dots, slashes, colons only — reject shell metacharacters and null bytes
- Port numbers: integers 1-65535 only
- File paths in COPY directives: reject
.. traversal and null bytes
Core Principles
- Verification-first: Examine codebase BEFORE adding ANY instruction
- Multi-arch: Support amd64/arm64, no hardcoded paths
- No HEALTHCHECK: Cannot verify health endpoints from code alone
- Multi-stage builds: Builder stage → minimal runtime stage
- Security: Non-root user (UID 10001+), pinned versions, no
:latest
- Layer optimization: Dependencies first, source second
Process
Step 1: Analyze Codebase
Before writing ANY Dockerfile instruction, verify:
[ ] Language/runtime detected (package.json, requirements.txt, go.mod, etc.)
[ ] Entry point identified (main file, start script)
[ ] Build command identified (if compilation needed)
[ ] Dependencies file location confirmed
[ ] Required environment variables documented
[ ] Exposed ports identified from code (NOT assumed)
Step 2: Generate Dockerfile
Structure:
# syntax=docker/dockerfile:1
# Build stage
FROM <base>:<pinned-version> AS builder
WORKDIR /app
# Install deps first (cache layer)
COPY <deps-file> .
RUN <install-deps>
# Copy source
COPY . .
RUN <build-command>
# Runtime stage
FROM <minimal-base>:<pinned-version>
WORKDIR /app
# Security: non-root user
RUN addgroup --gid 10001 appgroup && \
adduser --uid 10001 --ingroup appgroup --disabled-password appuser
USER appuser
# Copy artifacts from builder
COPY --from=builder --chown=appuser:appgroup /app/<artifact> .
EXPOSE <verified-port>
CMD ["<verified-entrypoint>"]
Language-specific bases:
| Language | Builder | Runtime |
|---|
| Node.js | node:<version>-alpine | node:<version>-alpine |
| Python | python:<version>-slim | python:<version>-slim |
| Go | golang:<version>-alpine | gcr.io/distroless/static |
| Java | eclipse-temurin:<version> | eclipse-temurin:<version>-jre-alpine |
| Rust | rust:<version>-alpine | gcr.io/distroless/cc |
Step 3: Validation Loop (Max 5 iterations)
docker build -t test-image:local .
docker run --rm test-image:local 2>&1 | head -50
Stop conditions:
- Container starts and responds correctly
- 5 iterations reached (escalate to user)
Gotchas
COPY . . before COPY package*.json && npm install busts the dependency cache on every source change — always copy deps files first
- Alpine-based images use
musl not glibc — native Node.js addons (bcrypt, sharp) may fail with cryptic errors. Use -slim for compatibility
RUN apt-get update && apt-get install without rm -rf /var/lib/apt/lists/* bloats the image by 30-100MB
- Multi-stage builds discard everything not explicitly
COPY --from=builder — forgetting to copy a config file causes silent runtime failures
EXPOSE is documentation only — it does NOT publish the port. You still need -p at runtime
- Running as root (default) means container compromise = full host access — always add a non-root user with UID 10001+
Anti-patterns to Avoid
FROM <image>:latest - Always pin versions
RUN apt-get update && apt-get install without cleanup
COPY . . before dependency installation
- Running as root
- Hardcoded secrets or credentials
- Assuming ports without code verification
- Adding HEALTHCHECK without verified endpoint
Output Format
When generating a Dockerfile, output:
- Analysis summary: What was detected in codebase
- Dockerfile: The generated file
- Build command: Exact command to build
- Run command: Exact command to test
- Notes: Any assumptions or manual verification needed
Source: dtsong/my-claude-setup — distributed by TomeVault.