Skip to main content
Glama
225-dockerfile-generation-system.md26.3 kB
# PRD: Dockerfile Generation System **Created**: 2025-11-18 **Status**: Complete **Owner**: Viktor Farcic **Last Updated**: 2025-11-30 (All milestones complete) ## Executive Summary Create an MCP prompt that generates production-ready, optimized Dockerfiles by analyzing local project directories. The prompt guides Claude Code to create language-agnostic Dockerfiles with multi-stage builds, security best practices, and build context optimization. This enables developers to containerize any application without deep Docker expertise. ## Problem Statement Developers need to containerize applications for Kubernetes deployment but face significant challenges: ### Current Pain Points - **Expertise gap**: Creating production-ready Dockerfiles requires deep knowledge of Docker best practices - **Framework diversity**: Each language/framework has specific optimization patterns that must be learned - **Security concerns**: Many Dockerfiles run as root, use bloated base images, expose vulnerabilities - **Build efficiency**: Poor .dockerignore configuration leads to slow, large builds - **Inconsistency**: Different developers create different Dockerfiles for similar projects ### Impact - Slow deployment adoption (manual Docker setup is a barrier) - Security vulnerabilities in production containers - Large image sizes increase deployment time and storage costs - Inconsistent environments across team members ## Solution Overview Create `shared-prompts/generate-dockerfile.md` that instructs Claude Code to: 1. **Analyze project structure** - Detect language, framework, dependencies, application type 2. **Select base images** - Choose appropriate, minimal base images 3. **Generate multi-stage Dockerfile** - Build stage + production stage for minimal final image 4. **Apply security hardening** - Non-root user, minimal packages, security best practices 5. **Optimize build context** - Generate .dockerignore to exclude unnecessary files ### Key Principles #### Language-Agnostic Design The prompt should provide **guidance patterns** that work across languages, not hardcoded templates: - Pattern: Separate dependency installation from source code copy (for caching) - Pattern: Multi-stage builds (build tools vs runtime) - Pattern: Minimal base images (alpine, slim, distroless where appropriate) - Pattern: Security hardening (non-root, pinned versions) The AI should figure out the specifics for any language/framework. #### Testing Strategy **Primary test projects:** - This project (Node.js/TypeScript) - A Go project **Goal**: If it works for these two different languages, the pattern should generalize to others. ## User Workflows ### Primary Workflow: Generate Dockerfile for Project **Steps**: 1. User is in project directory with source code 2. User invokes Dockerfile generation prompt 3. Claude Code analyzes project structure: - Identifies language/framework from files (package.json, go.mod, requirements.txt, etc.) - Determines application type (web server, API, CLI, worker) - Identifies dependencies and build requirements 4. Claude Code generates: - `Dockerfile` (multi-stage, optimized, secure) - `.dockerignore` (build context optimization) 5. User tests locally: `docker build -t myapp .` 6. User verifies: `docker run myapp` 7. Dockerfile ready for CI/CD pipeline (PRD #220) **Success Criteria**: - ✅ Dockerfile builds successfully without errors - ✅ Final image is minimal (appropriate for language) - ✅ Container runs as non-root user - ✅ Build context excludes unnecessary files - ✅ Multi-stage build separates build dependencies from runtime ## Technical Design ### Prompt Template Structure **File**: `shared-prompts/generate-dockerfile.md` **Input Requirements**: - User is in project directory - Project contains source code and dependency manifests **Output Specifications**: - `Dockerfile`: Production-ready multi-stage build - `.dockerignore`: Build context optimization **Prompt Guidance Areas**: #### 1. Project Analysis Guide the AI to: - Identify language from manifest files (package.json, go.mod, requirements.txt, pom.xml, etc.) - Determine framework from dependencies - Identify application type from project structure - Detect port requirements - Identify build tools needed #### 2. Base Image Selection Pattern Guide the AI to select appropriate base images: - Prefer minimal variants (alpine, slim) where possible - Use official images from trusted sources - Pin specific versions (not :latest) - Consider compiled vs interpreted languages - Use distroless or scratch for static binaries #### 3. Multi-Stage Build Pattern Guide the AI to structure: **Stage 1 (builder)**: - Start from image with build tools - Copy dependency manifests first (cache optimization) - Install dependencies - Copy source code - Build/compile application **Stage 2 (runtime)**: - Start from minimal runtime image - Copy only runtime artifacts from builder - Set non-root user - Configure port exposure - Set entrypoint/command #### 4. Security Hardening Pattern Guide the AI to apply: - Use specific image versions (not :latest) - Run as non-root user (USER 1000 or named user) - Minimize installed packages - Remove build tools from runtime image - Consider distroless/scratch for compiled languages #### 5. Build Context Optimization Guide the AI to generate .dockerignore with: - Version control directories (.git) - Build artifacts (language-specific) - Development files (.env.local, *.log) - Documentation (README.md, docs/) - Test files - IDE configurations ## Implementation Milestones ### Milestone 1: Core Prompt Template Created - [x] `shared-prompts/generate-dockerfile.md` created with language-agnostic guidance - [x] Project analysis guidance documented - [x] Base image selection patterns defined - [x] Multi-stage build pattern documented - [x] Security hardening guidance included ### Milestone 2: Tested with Node.js/TypeScript Project - [x] Tested with this project (dot-ai) - [x] Generated Dockerfile builds successfully - [x] Generated image runs as non-root - [x] Image size is reasonable - [x] .dockerignore appropriately excludes files ### Milestone 3: Best Practices Enhancement - [x] Identify and document Dockerfile best practices to incorporate - [x] Update prompt template to include best practices guidance - [x] Validate best practices with test projects ### Milestone 4: Existing Dockerfile Improvement - [x] Detect when Dockerfile already exists in project - [x] Read and analyze existing Dockerfile against best practices - [x] Identify improvements (security, multi-stage, non-root, image size, etc.) - [x] Preserve intentional customizations while fixing issues - [x] Present diff/comparison showing proposed changes with rationale - [x] Update .dockerignore if needed based on existing Dockerfile's COPY commands - [x] Validate improved Dockerfile builds and runs successfully ### Milestone 5: Tested with Go Project - [x] Tested with external Go project - [x] Generated Dockerfile builds successfully - [x] Generated image is minimal (distroless/scratch) - [x] Multi-stage build properly separates build from runtime - [x] Verifies pattern generalizes across languages ### Milestone 6: Documentation Complete - [x] `docs/mcp-prompts-guide.md` updated with Dockerfile generation guide - [x] Usage instructions documented (in prompt and guide) - [x] README.md updated with containerization capabilities - [x] Troubleshooting guidance provided (in prompt validation workflow) ## Success Criteria ### Functional Requirements - ✅ Generated Dockerfiles build successfully without errors - ✅ Generated images are minimal (appropriate for language) - ✅ Containers run as non-root user - ✅ Multi-stage builds separate build dependencies from runtime - ✅ .dockerignore excludes unnecessary files (reduces build context) ### Quality Requirements - ✅ Dockerfiles follow industry best practices - ✅ Generated files are human-readable and maintainable - ✅ Prompt works consistently across different languages (validated via Node.js and Go testing) ### Integration Requirements - ✅ Outputs ready for CI/CD integration (PRD #220) - ✅ Images work in local development (PRD #226) - ✅ Works seamlessly in Claude Code workflow ### Performance Requirements - ✅ Dockerfile generation completes in < 30 seconds - ✅ Generated images build in reasonable time - ✅ Multi-stage builds leverage caching effectively ## Risks & Mitigation ### Risk: Language-Specific Edge Cases **Impact**: Medium - Some projects may have unusual configurations **Probability**: Medium **Mitigation**: - Start with mainstream patterns - Allow users to provide additional context - Iterate based on real-world usage feedback - Document known edge cases ### Risk: Generated Dockerfiles Don't Build **Impact**: High - Breaks user workflow completely **Probability**: Low (if tested properly) **Mitigation**: - Test prompt with real projects (Node.js + Go) - Include validation guidance in prompt - Provide troubleshooting guidance in documentation - Iterate based on build failures ### Risk: Security Vulnerabilities in Generated Files **Impact**: High - Defeats security goals **Probability**: Low (with proper guidance) **Mitigation**: - Emphasize security patterns in prompt - Document security best practices - Consider adding vulnerability scanning recommendations ### Risk: Image Sizes Too Large **Impact**: Medium - Increases deployment time and costs **Probability**: Medium (depends on base image selection) **Mitigation**: - Emphasize multi-stage builds in prompt - Guide toward minimal base images - Test and validate image sizes in milestones ## Dependencies ### Prerequisites - User has Docker installed locally (for testing) - User is in project directory with source code ### External Dependencies - Docker/container runtime for local testing - Base images from Docker Hub or other registries - Language-specific package managers (npm, pip, go mod, maven, etc.) ### Integration Dependencies - PRD #220 (GitHub Actions) consumes generated Dockerfile - PRD #226 (Local K8s) uses generated images for local development ## Future Enhancements ### Potential Phase 2 Features - Platform-specific builds (ARM64, multi-arch) - Advanced BuildKit features (cache mounts, secrets) - Custom base image support (private registries) - Integrated vulnerability scanning recommendations ## Work Log ### 2025-11-18: PRD Creation **Completed Work**: - Created PRD #225 for Dockerfile Generation System - Defined language-agnostic approach (no hardcoded frameworks) - Focused on core Dockerfile + .dockerignore generation - Removed docker-compose (replaced by PRD #226 local K8s approach) - Simplified to 4 major milestones - Testing scope: Node.js/TypeScript (this project) + Go project **Design Decisions**: - Standalone prompt (no PRD #22 dependency) - Language-agnostic patterns (not framework-specific templates) - Local K8s development moved to separate PRD #226 - Examples and framework lists marked as TBD (to be determined during implementation) **Next Steps**: - Create PRD #220 (GitHub Actions CI/CD) - Create PRD #226 (Local Kubernetes Development) - Update PRD #22 to reflect focused analysis scope ### 2025-11-21: Milestone 1 & 2 Complete - Prompt Template Created and Node.js Testing **Duration**: Full development session **Primary Focus**: Create language-agnostic Dockerfile generation prompt and validate with dot-ai project **Completed PRD Items**: - [x] Created core prompt template at `.claude/commands/generate-dockerfile.md` - [x] Documented comprehensive project analysis guidance (language/framework detection) - [x] Defined base image selection patterns with multi-arch support - [x] Documented multi-stage build patterns (builder + runtime) - [x] Included security hardening guidance (non-root, minimal images, ENV handling) - [x] Tested iteratively with dot-ai project (Node.js/TypeScript) - [x] Generated Dockerfile builds successfully with kubectl, multi-stage, non-root - [x] Verified reasonable image size and minimal .dockerignore **Key Design Decisions**: - **Verification-first approach**: Added "verify everything before adding" as Critical Principle - **No assumptions**: Explicit prohibition on HEALTHCHECK, careful ENV variable handling - **Language-agnostic patterns**: Removed all language-specific recipes, focus on analysis principles - **Multi-arch requirement**: All instructions must support amd64, arm64, etc. - **Minimal .dockerignore**: Security/performance essentials only, not exhaustive lists - **Explicit COPY**: No `COPY . .`, only verified files/directories **Testing Approach**: - Iterative refinement through separate Claude Code instance - Each iteration addressed specific issues (kubectl, ENV vars, HEALTHCHECK, scripts/, etc.) - Final Dockerfile is production-ready for dot-ai project **Next Session Priorities**: - Test prompt with external Go project to validate language-agnostic approach - Move `.claude/commands/generate-dockerfile.md` to `shared-prompts/generate-dockerfile.md` - Update documentation (docs/mcp-guide.md, README.md) ### 2025-11-21: Design Decision - Add Validation & Testing Phase **Decision**: Add comprehensive validation and testing instructions to the prompt **Rationale**: - Current prompt generates Dockerfile/dockerignore but doesn't validate they actually work - Violates the "verify everything" principle - we generate but don't test - Users might receive broken Dockerfiles without Claude catching errors first - Manual testing in separate instance showed multiple iteration cycles needed to get it right - Automated validation would catch errors before presenting to user **Impact**: - **Requirements**: Add new validation phase after generation - **Prompt Enhancement**: Add Step 6: Build, Test, Fix, and Clean Up - **Success Criteria**: Dockerfile must successfully build and run, not just be generated - **User Experience**: Higher confidence - presented Dockerfiles are known to work **Implementation Approach**: After generating Dockerfile and .dockerignore, Claude should: 1. **Build the image**: `docker build -t [project-name]-test .` 2. **If build fails**: Analyze error, fix Dockerfile, retry (iterative) 3. **Run the container**: `docker run -d --name [project-name]-test [project-name]-test` 4. **Basic validation**: Check container is running, verify process started 5. **Clean up**: Remove container and image after validation 6. **Only then present to user**: With confidence it works **Code Impact**: Added Step 4 (Build, Test, and Iterate) to generate-dockerfile.md prompt **Owner**: Viktor Farcic **Status**: Implemented (2025-11-30) ### 2025-11-30: .dockerignore Guidance Enhancement **Duration**: Review and refinement session **Primary Focus**: Improve .dockerignore generation to be principle-based, not template-based **Completed Work**: - Rewrote Step 5 (.dockerignore) from template-based to principle-based guidance - Updated Success Criteria to reflect minimal .dockerignore approach (~10-15 lines) - Updated Example Workflow to show reasoning process instead of literal template - Validated prompt effectiveness: generated .dockerignore is 13 lines vs original 38 lines **Key Design Decisions**: - **.dockerignore derives from Dockerfile**: Only exclude what's relevant to COPY commands - **Two categories only**: Security patterns (inside copied dirs) + large directories (performance) - **No redundant exclusions**: Don't exclude directories the Dockerfile doesn't copy - **Target size**: ~10-15 lines maximum **Next Session Priorities**: - Implement Step 6: Build, Test, Fix, and Clean Up (validation phase) - Test with Go project (Milestone 5) ### 2025-11-30: Design Decision - Add Existing Dockerfile Improvement Milestone **Decision**: Add Milestone 4 for improving existing Dockerfiles **Rationale**: - Current command assumes no Dockerfile exists and generates from scratch - Many projects already have Dockerfiles that need improvement, not replacement - Same best practices apply whether creating new or improving existing - Should be done before testing with other languages (Go) to ensure the improvement flow works **Impact**: - **New Milestone 4**: Existing Dockerfile Improvement - **Renumbered**: Go testing → Milestone 5, Documentation → Milestone 6 - **Removed from Future Enhancements**: "Dockerfile optimization for existing files" now in scope **Implementation Approach**: 1. Detect if Dockerfile exists in project directory 2. If exists: read, analyze against best practices, propose improvements 3. Preserve intentional customizations (comments, special configurations) 4. Show diff/comparison with rationale for each change 5. Apply same validation (build, run, clean up) to improved Dockerfile ### 2025-11-30: Milestone 3 Complete - Best Practices Enhancement **Duration**: Full development session **Primary Focus**: Research, document, and integrate Dockerfile best practices into prompt **Completed PRD Items**: - [x] Researched best practices from Docker docs, OWASP, Sysdig, Hadolint, and industry sources - [x] Created comprehensive research document (`tmp/best-practices.md`) - [x] Restructured prompt with consolidated "Best Practices Reference" section - [x] Validated with dot-ai project - kubectl detected, non-root user, proper .dockerignore **Key Design Decisions**: - **Consolidated best practices section**: Moved scattered practices into single reference section with 4 categories (Security, Image Selection, Build Optimization, Maintainability) - **Table format**: Best practices presented as scannable tables with practice name and description - **Contextual application**: Added guidance that practices apply "when relevant" - not rigid rules - **Thoroughness over speed**: Added critical principle emphasizing deep analysis over quick generation - **Principle-based system dependencies**: Enhanced guidance without prescribing specific patterns **Prompt Structure Changes**: - Reduced from 5 process steps to 3 cleaner steps (Analyze, Generate, .dockerignore) - Added checklists for Builder stage, Runtime stage, and Package installation - Added tooling recommendations (hadolint, trivy) in output section - Enhanced Success Criteria with comprehensive Dockerfile and .dockerignore checklists **Validation Results**: - Generated Dockerfile correctly identified kubectl as runtime dependency - Runs as non-root user (appuser, UID 1000) - Installs kubectl with proper multi-arch detection - .dockerignore reduced to 15 lines (within target of 10-15) - Creates session directory with proper permissions - Sets appropriate environment variables **Next Session Priorities**: - Implement Milestone 4: Existing Dockerfile Improvement - Or proceed to Milestone 5: Go Project Testing ### 2025-11-30: Milestone 4 Complete - Existing Dockerfile Improvement **Duration**: Development session **Primary Focus**: Add ability to detect and improve existing Dockerfiles **Completed PRD Items**: - [x] Added Step 0 to detect existing Dockerfile and .dockerignore - [x] Updated Step 2 to handle both generation and improvement flows - [x] Added evaluation against best practices checklists for existing files - [x] Added guidance to preserve intentional customizations (comments, ENV vars, configs) - [x] Added "Changes made" output format showing what was changed and why - [x] Updated Step 3 for .dockerignore improvement (remove redundant, add missing) - [x] Validated with dot-ai project's original Dockerfile **Additional Work - Language-Agnostic Refactoring**: - Rewrote Step 1 (Analyze Project Structure) from lookup tables to analysis principles - Changed Language Detection and Version Detection to be exploratory, not prescriptive - Generalized Step 2 examples from Node.js-specific to pattern-based templates - Added yum/dnf package manager examples alongside apt-get and apk - Updated Example Workflows to show both new generation and improvement scenarios **Validation Results** (tested with original tmp/Dockerfile): | Original Issue | Result | |---------------|--------| | Running as root (no USER) | ✅ Added non-root user (dotai, UID 1000) | | Missing `--no-install-recommends` | ✅ Added to apt-get install | | Missing `ca-certificates` | ✅ Added for curl HTTPS | | No session dir ownership | ✅ Added `chown -R dotai:dotai` | | .dockerignore 38 lines | ✅ Reduced to 9 lines (minimal) | | Preserved: multi-stage, kubectl, ENV vars, comments | ✅ All kept | **Key Design Decisions**: - **Unified flow**: Same process for new and existing, only Step 2 output differs - **Checklists for validation**: Same checklists used for generation and improvement - **Conservative preservation**: Keep anything that looks intentional (comments, custom configs) **Next Session Priorities**: - Test with Go project (Milestone 5) to validate language-agnostic approach - Complete documentation (Milestone 6) ### 2025-11-30: Validation Phase Implementation **Duration**: Development session **Primary Focus**: Implement Step 4 (Build, Test, and Iterate) and prompt enhancements **Completed Work**: - Implemented Step 4: Build, Test, and Iterate (validation phase) - 4.1 Build validation - 4.2 Run validation (container state check based on application type) - 4.3 Log analysis (using project knowledge, language-agnostic) - 4.4 Linting with hadolint (if available, skip if not) - 4.5 Security scan with trivy (if available, skip if not) - 4.6 Iteration loop (max 5 attempts before asking user) - 4.7 Cleanup (always runs, success or failure) - Added Environment Variable Detection to Step 1 (item 8) - Changed UID recommendation from 1000+ to 10001+ (avoids base image user conflicts) - Added online version lookup guidance to Version Detection - Updated Example Workflows to include validation steps - Added Validation Checklist to Success Criteria - Moved hadolint/trivy from "recommended next steps" into automated validation **Key Design Decisions**: - **Language-agnostic log analysis**: AI uses project knowledge to interpret logs, no prescriptive error patterns - **Optional tooling**: hadolint and trivy run if installed, skip gracefully if not - **UID 10001+**: Avoids conflicts with common base image users (e.g., node user is often UID 1000) - **Principle-based env var detection**: No language-specific patterns, let AI figure it out **Validation Results** (tested with dot-ai project): | Mode | Test | Result | |------|------|--------| | New generation | UID | ✅ 10001 from start (no validation fix needed) | | New generation | ENV vars | ✅ 4 of 5 detected (TRANSPORT_TYPE, HOST, PORT, DOT_AI_SESSION_DIR) | | Improvement | Non-root user | ✅ Added (dotai, UID 10001) | | Improvement | --no-install-recommends | ✅ Added | | Improvement | ca-certificates | ✅ Added | | Improvement | Preserved customizations | ✅ All comments, ENV vars, .tgz approach kept | | Improvement | .dockerignore | ✅ Reduced from 38 to 12 lines | **Next Session Priorities**: - Test with Go project (Milestone 5) to validate language-agnostic approach - Complete documentation (Milestone 6) ### 2025-11-30: Milestone 5 Complete - Go Project Testing & CI Integration **Duration**: Development session **Primary Focus**: Validate language-agnostic approach with Go project and ensure CI integration **Completed PRD Items**: - [x] Tested with external Go project (silly-demo) - [x] Generated Dockerfile builds successfully - [x] Generated image is minimal (distroless/scratch) - [x] Multi-stage build properly separates build from runtime - [x] Verifies pattern generalizes across languages **Go Project Testing Results** (silly-demo): | Test | New Generation | Improvement Flow | |------|----------------|------------------| | Base image | `scratch` | `distroless/static:nonroot` | | Non-root user | ✅ UID 10001 | ✅ `nonroot:nonroot` | | Multi-arch | ✅ TARGETOS/TARGETARCH | ✅ Auto-detect | | Static binary | ✅ CGO_ENABLED=0 | ✅ CGO_ENABLED=0 | | CA certificates | ✅ Copied from builder | ✅ Built into distroless | | Vendor support | ✅ `-mod=vendor` | ✅ Preserved | **Key Improvements Over Original silly-demo Dockerfile**: - Fixed security: Added non-root user (original ran as root) - Fixed portability: Removed hardcoded amd64, now multi-arch - Fixed HTTPS: Added CA certificates (original would fail HTTPS calls) - Added build optimization: `-ldflags="-s -w"` for smaller binary - Cleaned up redundant operations (mkdir, chmod, go mod download with vendor) **dot-ai Project Testing** (Node.js): - Generated new Dockerfile with multi-stage build, non-root user, kubectl - Verified version tool reads from package.json correctly - Confirmed CI will validate Dockerfile during PR checks **CI Workflow Updates**: - Removed obsolete `npm pack` step (no longer needed - builds from source) - Removed unused `PACKAGE_VERSION` build-arg - Verified integration tests build Docker image and deploy to Kind cluster **Key Findings**: - Language-agnostic approach works: Same prompt handles Node.js and Go correctly - Prompt adapts base image selection: Alpine for Node.js, scratch/distroless for Go - Improvement flow preserves intentional customizations while fixing issues ### 2025-11-30: Milestone 6 Complete - Documentation **Duration**: Development session **Primary Focus**: Move prompt to MCP shared-prompts and complete documentation **Completed PRD Items**: - [x] `docs/mcp-prompts-guide.md` updated with Dockerfile generation guide - [x] Usage instructions documented (in prompt and guide) - [x] README.md updated with containerization capabilities - [x] Troubleshooting guidance provided (in prompt validation workflow) **Completed Work**: - Moved `generate-dockerfile.md` from `.claude/commands/` to `shared-prompts/` with YAML frontmatter - Added to `docs/mcp-prompts-guide.md`: Development Prompts entry and Containerization workflow - Updated README.md Shared Prompts section with PRD Management and Dockerfile Generation - Cleaned up documentation: removed non-existent prompts (context-save, context-load, tests-reminder), added missing prd-close - Removed outdated "Managing Prompts" section from mcp-prompts-guide.md **PRD Status**: All milestones complete. Ready for merge.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/vfarcic/dot-ai'

If you have feedback or need assistance with the MCP directory API, please join our Discord server