Awesome-omni-skill dockerfile-validator
Comprehensive toolkit for validating, linting, and securing Dockerfiles. Use this skill when validating Dockerfile syntax, checking security best practices, optimizing image builds. Applies to all Dockerfile variants (Dockerfile, Dockerfile.prod, Dockerfile.dev, etc.).
git clone https://github.com/diegosouzapw/awesome-omni-skill
T=$(mktemp -d) && git clone --depth=1 https://github.com/diegosouzapw/awesome-omni-skill "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/tools/dockerfile-validator" ~/.claude/skills/diegosouzapw-awesome-omni-skill-dockerfile-validator && rm -rf "$T"
skills/tools/dockerfile-validator/SKILL.mdDockerfile Validator
Overview
Comprehensive toolkit for validating Dockerfiles with syntax checking, security scanning, best practices enforcement, and build optimization analysis. This skill uses a single self-contained script (
dockerfile-validate.sh) that handles everything: tool installation, validation, and cleanup.
Key Features:
- ✅ Single script execution - no dependencies on other scripts
- ✅ Auto-installs hadolint and Checkov in Python venvs if not found
- ✅ Runs all 4 validation stages (syntax, security, best practices, optimization)
- ✅ Auto-cleanup on exit using bash trap (success or failure)
- ✅ Zero configuration required
When to Use This Skill
Invoke this skill when:
- Validating Dockerfile syntax and structure
- Checking Dockerfiles for security vulnerabilities
- Optimizing Docker image build performance
- Ensuring adherence to official Docker best practices
- Debugging Dockerfile errors or build issues
- Performing security audits of container images
- The user asks to "validate", "lint", "check", or "optimize" a Dockerfile
- Reviewing Dockerfiles before committing to version control
- Analyzing existing Dockerfiles for improvements
Do NOT Use This Skill For
- Generating new Dockerfiles (use dockerfile-generator instead)
- Building or running containers (use docker build/run commands)
- Debugging running containers (use docker logs, docker exec)
- Managing Docker images or registries
Quick Start
Single command to validate any Dockerfile:
bash scripts/dockerfile-validate.sh Dockerfile
That's it! The script automatically:
- Checks if hadolint and Checkov are installed
- Installs them temporarily in Python venvs if needed
- Runs all 4 validation stages (syntax, security, best practices, optimization)
- Cleans up temporary installations on exit
Validation Workflow
The
dockerfile-validate.sh script runs a comprehensive 4-stage validation:
┌─────────────────────────────────────────────────────────┐ │ Auto-Install (if needed) │ │ ├─> Check for hadolint and Checkov │ │ ├─> Install in Python venvs if not found │ │ └─> Set TEMP_INSTALL=true (triggers cleanup on exit) │ └─────────────────────────────────────────────────────────┘ │ ┌─────────────────────────────────────────────────────────┐ │ [1/4] Syntax Validation (hadolint) │ │ ├─> Dockerfile syntax checking │ │ ├─> Instruction validation │ │ ├─> Shell script validation (via ShellCheck) │ │ └─> 100+ built-in linting rules │ └─────────────────────────────────────────────────────────┘ │ ┌─────────────────────────────────────────────────────────┐ │ [2/4] Security Scan (Checkov) │ │ ├─> Security policy validation │ │ ├─> Hardcoded secret detection │ │ ├─> Port exposure checks │ │ ├─> USER directive validation │ │ └─> 50+ security policies │ └─────────────────────────────────────────────────────────┘ │ ┌─────────────────────────────────────────────────────────┐ │ [3/4] Best Practices Validation (custom) │ │ ├─> Base image tag validation (:latest check) │ │ ├─> USER directive enforcement (non-root) │ │ ├─> HEALTHCHECK presence │ │ ├─> Layer efficiency (RUN command count) │ │ ├─> Package cache cleanup verification │ │ ├─> Hardcoded secrets detection │ │ └─> COPY ordering for build cache efficiency │ └─────────────────────────────────────────────────────────┘ │ ┌─────────────────────────────────────────────────────────┐ │ [4/4] Optimization Analysis (custom) │ │ ├─> Base image size analysis (Alpine suggestions) │ │ ├─> Multi-stage build opportunities │ │ ├─> Layer count optimization │ │ ├─> .dockerignore file check │ │ └─> Build structure recommendations │ └─────────────────────────────────────────────────────────┘ │ ┌─────────────────────────────────────────────────────────┐ │ Auto-Cleanup (bash trap - always runs) │ │ └─> Remove temp venvs if TEMP_INSTALL=true │ └─────────────────────────────────────────────────────────┘
Cleanup Guarantee: Uses
trap cleanup EXIT INT TERM to ensure cleanup runs on:
- ✅ Normal exit
- ✅ Validation failure
- ✅ Ctrl+C (interrupt)
- ✅ Script error
Core Capabilities
1. Syntax Validation with hadolint
Purpose: Lint Dockerfile syntax and catch common mistakes before building.
Tool: hadolint - A Dockerfile linter that validates instructions and embedded bash commands using ShellCheck.
Installation:
Tools are automatically installed by the validation script if not found. For permanent installation:
# macOS brew install hadolint # Linux wget -O ~/.local/bin/hadolint https://github.com/hadolint/hadolint/releases/latest/download/hadolint-Linux-x86_64 chmod +x ~/.local/bin/hadolint # Docker (fallback option) docker pull hadolint/hadolint
Workflow:
# Run hadolint on Dockerfile hadolint Dockerfile # Run with JSON output for parsing hadolint --format json Dockerfile # Run with specific rules ignored hadolint --ignore DL3006 --ignore DL3008 Dockerfile # Using Docker if not installed docker run --rm -i hadolint/hadolint < Dockerfile
Common Issues Detected:
DL-prefixed rules (hadolint-specific):
- Use absolute WORKDIR pathsDL3000
- For some bash commands make no sense in a Docker containerDL3001
- Last USER should not be rootDL3002
- Use WORKDIR to switch directoriesDL3003
- Do not use sudoDL3004
- Always tag image versions (avoid :latest)DL3006
- Using latest is not recommendedDL3007
- Pin versions in apt-get installDL3008
- Delete apt-cache after installingDL3009
- Pin versions in pip installDL3013
- Use -y switch for apt-getDL3014
- Avoid additional packages with apt-getDL3015
- Pin versions in npm installDL3016
- Pin versions in apk addDL3018
- Use --no-cache with apk addDL3019
- Use COPY instead of ADD for filesDL3020
- COPY from previous stages should reference by nameDL3021
- COPY --from should reference a previously defined FROM aliasDL3022
- Use JSON notation for CMD and ENTRYPOINTDL3025
- Multiple consecutive RUN instructions (combine for layer efficiency)DL3059
SC-prefixed rules (ShellCheck for RUN commands):
- Not following sourced filesSC1091
- Quote to prevent word splittingSC2046
- Double quote to prevent globbingSC2086
- Use cd ... || exit for error handlingSC2164
Rule Severity Levels:
- error - Will likely cause build failure or runtime issues
- warning - Violates best practices, should be fixed
- info - Suggestions for improvement
- style - Code style preferences
Best Practices:
- Run hadolint before every docker build
- Integrate into CI/CD pipelines
- Configure .hadolint.yaml for project-specific rules
- Address errors before warnings
- Use inline ignore comments sparingly with justification
2. Security Scanning with Checkov
Purpose: Detect security misconfigurations and vulnerabilities before image deployment.
Tool: Checkov - Policy-as-code security scanner with 50+ built-in Dockerfile policies.
Installation:
The validation script automatically installs Checkov in an isolated Python venv if not found. For permanent installation:
# Install directly pip3 install checkov # macOS Homebrew brew install checkov # Verify installation checkov --version
Workflow:
# Scan a Dockerfile checkov -f Dockerfile --framework dockerfile # Scan a directory (finds all Dockerfiles) checkov -d . --framework dockerfile # Scan with compact output (only failures) checkov -f Dockerfile --framework dockerfile --compact # Scan with JSON output checkov -f Dockerfile --framework dockerfile -o json # Skip specific checks checkov -f Dockerfile --framework dockerfile --skip-check CKV_DOCKER_2
Common Security Checks:
General Security:
- Ensure port 22 (SSH) is not exposedCKV_DOCKER_1
- Ensure HEALTHCHECK instruction existsCKV_DOCKER_2
- Ensure user is created and used (not root)CKV_DOCKER_3
- Ensure ADD is not used (prefer COPY)CKV_DOCKER_4
- Ensure update without install is not used aloneCKV_DOCKER_5
- Ensure SHELL instruction uses -o pipefailCKV_DOCKER_6
- Ensure base image uses specific version tagCKV_DOCKER_7
- Ensure last USER is not rootCKV_DOCKER_8
- Ensure apt-get dist-upgrade is not usedCKV_DOCKER_9
- Ensure yum update is not used aloneCKV_DOCKER_10
Package Management:
- Check for missing package manager cache cleanup
- Verify version pinning for installed packages
- Detect use of --no-install-recommends for apt-get
Secrets Detection:
- Scan for potential secrets in ENV or ARG
- Detect hardcoded credentials
- Identify exposed API keys or tokens
Output Formats:
- Human-readable console output (default)cli
- JSON format for programmatic parsingjson
- SARIF format for IDE integrationsarif
- GitLab security dashboard formatgitlab_sast
- JUnit XML for CI integrationjunitxml
Understanding Results:
Check: "Ensure that HEALTHCHECK instructions have been added to container images" FAILED for resource: Dockerfile. File: /Dockerfile:1-20 Guide: https://docs.bridgecrew.io/docs/ensure-that-healthcheck-instructions-have-been-added-to-container-images 1 | FROM node:18 20 | CMD ["node", "server.js"]
Suppressing False Positives:
Add inline comments to suppress specific checks:
# checkov:skip=CKV_DOCKER_2:Health check not applicable for this init container FROM alpine:3.21 ...
Exit Codes:
- All checks passed0
- One or more checks failed1
Best Practices:
- Run Checkov after hadolint (syntax first, then security)
- Address high-severity findings first
- Document all suppressions with clear justification
- Integrate into CI/CD pipelines
- Review new policies regularly
- Combine with image vulnerability scanning (e.g., trivy, snyk)
3. Best Practices Validation
Purpose: Ensure Dockerfiles follow official Docker best practices and current recommendations.
Custom Validation Checks:
1. Base Image Validation:
# Check for :latest tag usage grep -E "^FROM.*:latest" Dockerfile # Recommend specific tags or digest pinning # Good: FROM alpine:3.21 # Better: FROM alpine:3.21@sha256:digest
2. Multi-Stage Build Detection:
# Count FROM statements grep -c "^FROM" Dockerfile # Single FROM suggests potential for multi-stage optimization
3. USER Directive Check:
# Ensure USER is set before CMD/ENTRYPOINT # Check that last USER is not root grep "^USER" Dockerfile
4. HEALTHCHECK Presence:
# Verify HEALTHCHECK is defined for services grep "^HEALTHCHECK" Dockerfile
5. Layer Efficiency:
# Count RUN commands (>5 suggests combination opportunity) grep -c "^RUN" Dockerfile # Check for apt-get update separated from install grep -A1 "^RUN.*apt-get update" Dockerfile
6. Package Manager Cache Cleanup:
# Verify cache cleanup in same RUN layer grep "rm -rf /var/lib/apt/lists" Dockerfile grep "--no-cache" Dockerfile # for apk
Best Practices Checklist:
Base Images:
- ✓ Use specific version tags, not :latest
- ✓ Consider Alpine variants for smaller size
- ✓ Pin to digest for reproducibility
- ✓ Use official images from verified publishers
- ✓ Scan base images for vulnerabilities
Layer Optimization:
- ✓ Combine related RUN commands with &&
- ✓ Order instructions from least to most frequently changing
- ✓ COPY package files before source code
- ✓ Clean up package manager caches in same layer
- ✓ Use .dockerignore to exclude unnecessary files
Security:
- ✓ Run as non-root user (USER directive)
- ✓ Don't install unnecessary packages (--no-install-recommends)
- ✓ Don't hardcode secrets (use build secrets or runtime configs)
- ✓ Use COPY instead of ADD (unless extracting archives)
- ✓ Avoid curl | bash installations
Multi-Stage Builds:
- ✓ Separate build dependencies from runtime
- ✓ Name stages explicitly (FROM ... AS stagename)
- ✓ Copy only necessary artifacts between stages
- ✓ Use minimal runtime base images
Runtime Configuration:
- ✓ Define HEALTHCHECK for services
- ✓ Use exec form for ENTRYPOINT and CMD
- ✓ Set WORKDIR to absolute paths
- ✓ Document exposed ports with EXPOSE
- ✓ Add metadata with LABEL
Build Performance:
- ✓ Leverage build cache by proper instruction ordering
- ✓ Use BuildKit features (--mount=type=cache)
- ✓ Minimize context size with .dockerignore
- ✓ Parallelize multi-stage builds when possible
4. Optimization Analysis
Purpose: Identify opportunities to reduce image size, build time, and layer count.
Optimization Categories:
1. Image Size Reduction:
# Bad: Full distro FROM ubuntu:22.04 RUN apt-get update && apt-get install -y curl # Good: Minimal distro FROM alpine:3.21 RUN apk add --no-cache curl # Better: Multi-stage with distroless FROM golang:1.21 AS build WORKDIR /app COPY . . RUN go build -o myapp FROM gcr.io/distroless/base-debian11 COPY --from=build /app/myapp / ENTRYPOINT ["/myapp"]
2. Layer Optimization:
# Bad: Separate RUN commands (creates many layers) RUN apt-get update RUN apt-get install -y curl RUN apt-get install -y git RUN apt-get install -y vim # Good: Combined RUN (single layer) RUN apt-get update && apt-get install -y --no-install-recommends \ curl \ git \ vim \ && rm -rf /var/lib/apt/lists/*
3. Build Cache Efficiency:
# Bad: Copy all, then install dependencies COPY . /app RUN pip install -r requirements.txt # Good: Copy dependency file first COPY requirements.txt /app/ RUN pip install -r requirements.txt COPY . /app
4. Multi-Stage Build Opportunities:
# Detects single-stage builds that could benefit from separation # Look for: # - Build tools installed but not needed at runtime # - Source code copied but only binary needed # - Development dependencies mixed with runtime
Optimization Metrics:
- Layer count: Fewer layers = smaller image
- Image size: Minimal base + cleanup = smaller download
- Build time: Cache hits + parallel stages = faster builds
- Attack surface: Fewer packages = fewer vulnerabilities
Reference Documentation:
Load detailed best practices:
references/docker_best_practices.md - Official Docker recommendations references/optimization_guide.md - Layer and size optimization techniques
5. .dockerignore Validation
Purpose: Ensure build context is optimized by excluding unnecessary files.
Validation Checks:
# Check if .dockerignore exists if [ ! -f .dockerignore ]; then echo "WARNING: .dockerignore file not found" fi # Common patterns that should be included .git .gitignore README.md .env *.log node_modules *.md .dockerignore Dockerfile* docker-compose*.yml
Benefits of .dockerignore:
- Reduces build context size
- Faster builds (less data to transfer)
- Prevents accidental secret leaks
- Excludes development-only files
Best Practices:
- Always create .dockerignore for non-trivial projects
- Include .git directory
- Exclude local configuration files (.env, *.local)
- Exclude documentation unless needed in image
- Exclude test files and test data
- Pattern syntax similar to .gitignore
Tool Prerequisites
The validation script automatically installs tools if not found. No manual installation required.
For permanent installations:
# Install hadolint brew install hadolint # macOS # Install Checkov pip3 install checkov
Minimum Versions:
- hadolint: >= 2.12.0
- Checkov: Latest (for newest policies)
- Python: >= 3.8 (for temporary installations)
- Docker: >= 20.10 (optional, for testing builds)
Testing Auto-Install and Cleanup:
To test the temporary installation and cleanup functionality even when tools are already installed:
# Force temporary installation for testing FORCE_TEMP_INSTALL=true bash scripts/dockerfile-validate.sh Dockerfile
This will:
- Install hadolint and Checkov in temporary Python venvs
- Run all validations using the temporary installations
- Clean up temporary venvs on exit (success or failure)
Handling Missing Tools
When validation tools are not installed:
Workflow for Missing Tools
-
Detect Missing Tool:
- Attempt to run hadolint or Checkov
- If command fails, note which tool is missing
-
Complete Available Validations:
- Continue with custom best practices checks
- Provide partial validation results
- Clearly indicate which checks were skipped
-
Prompt User for Installation:
For hadolint:
hadolint is not installed. The script will automatically install it temporarily. For permanent installation: - macOS: brew install hadolint - Linux: wget -O ~/.local/bin/hadolint https://github.com/hadolint/hadolint/releases/latest/download/hadolint-Linux-x86_64 && chmod +x ~/.local/bin/hadolint - Docker: docker pull hadolint/hadolint hadolint provides comprehensive Dockerfile linting and best practice checking.For Checkov:
Checkov is not installed. Would you like to install it? Installation options: - Recommended: pip3 install checkov - macOS: brew install checkov Checkov provides security scanning with 50+ Dockerfile policies. Install and rerun validation? (y/N) -
If User Chooses to Install:
- Provide installation command
- Wait for completion
- Verify:
orhadolint --versioncheckov --version - Rerun complete validation
-
If User Declines:
- Continue with partial results
- Document skipped checks
- Suggest installing for future validations
Tool Priority
Required (always run):
- Custom best practices validation
- File existence checks
Recommended (offer installation if missing):
- hadolint - Syntax and best practices linting
- Checkov - Security scanning
Optional:
- docker - For test builds
- trivy - For vulnerability scanning (complementary)
Error Troubleshooting
Common Issues and Solutions
Error: FROM instruction must be first non-comment
Solution: Move ARG that defines base image tag before FROM ARG VERSION=18 FROM node:${VERSION}
Error: Unknown instruction (typo)
Solution: Check instruction spelling (RUN, COPY, FROM, etc.) Common typos: RUNS, COPIES, FRUM
Error: Chained RUN command fails
Solution: Add set -e or check individual command success RUN apt-get update && apt-get install -y package || exit 1
Error: COPY failed: file not found
Solution: Check file path is relative to build context Verify file exists and not excluded by .dockerignore
Security: Hardcoded secrets detected
Solution: Use build secrets (BuildKit) # Instead of: ENV API_KEY=secret123 # Use: docker build --secret id=api_key,src=api_key.txt
Performance: Slow builds
Solution: 1. Optimize layer caching (COPY package files first) 2. Use .dockerignore to reduce context 3. Enable BuildKit: export DOCKER_BUILDKIT=1 4. Use multi-stage builds
Resources
scripts/
dockerfile-validate.sh
- Single self-contained validation script
- Auto-installs hadolint and Checkov if needed
- Runs all 4 validation stages (syntax, security, best practices, optimization)
- Auto-cleanup on exit
- Usage:
bash scripts/dockerfile-validate.sh [Dockerfile]
examples/
good-example.Dockerfile - Demonstrates best practices and optimal structure
bad-example.Dockerfile - Common mistakes and anti-patterns
security-issues.Dockerfile - Intentional security vulnerabilities for testing
python-optimized.Dockerfile - Python-specific optimizations and multi-stage build
golang-distroless.Dockerfile - Minimal Go application using distroless base image
.dockerignore.example - Example .dockerignore for build context optimization
references/
docker_best_practices.md - Official Docker best practices and recommendations
optimization_guide.md - Layer optimization and image size reduction techniques
security_checklist.md - Container security best practices
Mandatory Workflow Requirements
IMPORTANT: When using this skill, you MUST follow these steps in order:
Pre-Validation (Required)
- Read the Dockerfile first - Always use the Read tool to examine the Dockerfile before running validation. This helps you understand the context and provide better recommendations.
Validation (Required)
- Run the validation script - Execute
to run all 4 validation stages.bash scripts/dockerfile-validate.sh <Dockerfile>
Post-Validation (Required)
-
Summarize findings by severity - After validation completes, provide a clear summary organized by:
- Critical issues (security vulnerabilities, hardcoded secrets)
- High priority (missing USER, HEALTHCHECK, :latest tags)
- Medium priority (layer optimization, version pinning)
- Low priority (style, informational)
-
Propose specific fixes - For each issue found, provide concrete code examples showing how to fix it. You MUST use the Read tool to load the appropriate reference files before proposing fixes:
- For security-related fixesreferences/security_checklist.md
- For performance/size improvementsreferences/optimization_guide.md
- For general best practicesreferences/docker_best_practices.md
Note: Always explicitly read reference files during the post-validation phase to ensure fix recommendations follow authoritative patterns, even if you have prior knowledge of the content.
-
Offer to apply fixes - Ask the user if they want you to apply the proposed fixes to their Dockerfile.
Reference File Usage
IMPORTANT: After running validation, you MUST use the Read tool to explicitly load the appropriate reference files before proposing fixes. This ensures fix recommendations are accurate and follow authoritative patterns.
Workflow:
- Identify issue types from validation output (security, optimization, best practices)
- Use the Read tool to load the matching reference file(s)
- Apply patterns from the reference files when proposing fixes
| Issue Type | Reference File | Action |
|---|---|---|
| Security issues (secrets, USER, ports) | | Read before proposing security fixes |
| Size/performance optimization | | Read before proposing optimization fixes |
| General best practices | | Read before proposing best practice fixes |
Example:
# After validation finds security issues: 1. Use Read tool: Read references/security_checklist.md 2. Apply fix patterns from the file to the specific issues found 3. Propose fixes with code examples based on reference content
Workflow Examples
Example 1: Validate a Single Dockerfile
User: "Validate my Dockerfile" Steps: 1. Read the Dockerfile using Read tool to understand structure 2. Run validation script: bash scripts/dockerfile-validate.sh Dockerfile 3. Review output from all 4 stages (hadolint, Checkov, best practices, optimization) 4. Summarize findings organized by severity (critical → low) 5. Use Read tool to load relevant reference files: - Read references/security_checklist.md (if security issues found) - Read references/optimization_guide.md (if optimization issues found) - Read references/docker_best_practices.md (if best practice issues found) 6. Propose specific fixes with code examples based on reference content 7. Ask user: "Would you like me to apply these fixes?" 8. Apply fixes if user approves
Example 2: Comprehensive Multi-Dockerfile Validation
User: "Check all Dockerfiles in my project" Steps: 1. Find all Dockerfile* files 2. Validate each sequentially 3. Aggregate results 4. Identify common issues across files 5. Provide unified report 6. Suggest project-wide improvements
Example 3: Security Audit
User: "Security audit my Dockerfile" Steps: 1. Run Checkov security scan 2. Run hadolint for security rules (DL3* series) 3. Check for hardcoded secrets 4. Verify USER directive 5. Check base image vulnerabilities 6. Provide security-focused report 7. Prioritize critical findings
Example 4: Optimization Review
User: "How can I optimize my Dockerfile?" Steps: 1. Analyze current layer structure 2. Identify multi-stage opportunities 3. Check build cache efficiency 4. Suggest base image alternatives 5. Calculate potential size savings 6. Provide before/after comparison 7. Implement optimizations if approved
Integration with Other Skills
This skill works well in combination with:
- dockerfile-generator - Generate optimized Dockerfiles
- k8s-yaml-validator - Validate Kubernetes deployments that reference Docker images
- helm-validator - Validate Helm charts with container configurations
Notes
- Always validate before building images
- Address security issues before optimizations
- Test builds after applying fixes
- Version pin base images for reproducibility
- Use multi-stage builds for compiled languages
- Keep production images minimal (distroless, Alpine)
- Never commit Dockerfiles with hardcoded secrets
- Document inline suppressions with clear justification
- Regularly update base images for security patches
- Integrate validation into CI/CD pipelines
Sources
This skill is based on comprehensive research from authoritative sources:
Official Docker Documentation:
Security Guidelines:
Best Practices Resources: