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.).
Overall
score
93%
Does it follow best practices?
Validation for skill structure
This skill validates Dockerfiles using a single self-contained script (dockerfile-validate.sh) that handles everything: tool installation, validation, and cleanup.
Key Features:
Single command to validate any Dockerfile:
bash scripts/dockerfile-validate.sh DockerfileThe script automatically checks for hadolint and Checkov, installs them temporarily in Python venvs if needed, runs all 4 validation stages, then cleans up on exit via trap cleanup EXIT INT TERM (ensures cleanup on normal exit, validation failure, Ctrl+C, and script errors).
The dockerfile-validate.sh script runs a comprehensive 4-stage validation:
TEMP_INSTALL=true to trigger cleanup on exitTEMP_INSTALL=trueWorkflow:
# 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 < DockerfileFor the full list of DL-prefixed (hadolint) and SC-prefixed (ShellCheck) rules, see references/docker_best_practices.md.
Rule Severity Levels: error → warning → info → style
Best Practices:
.hadolint.yaml for project-specific rulesInstallation (permanent):
pip3 install checkov # direct
brew install checkov # macOSWorkflow:
# Scan a Dockerfile
checkov -f Dockerfile --framework dockerfile
# Scan a directory (finds all Dockerfiles)
checkov -d . --framework dockerfile
# Compact output (failures only)
checkov -f Dockerfile --framework dockerfile --compact
# Skip specific checks
checkov -f Dockerfile --framework dockerfile --skip-check CKV_DOCKER_2For the full list of CKV_DOCKER_* security checks, see references/security_checklist.md.
Suppressing False Positives:
# checkov:skip=CKV_DOCKER_2:Health check not applicable for this init container
FROM alpine:3.21Best Practices:
Custom Validation Checks:
# Check for :latest tag usage
grep -E "^FROM.*:latest" Dockerfile
# Count FROM statements (single FROM = multi-stage opportunity)
grep -c "^FROM" Dockerfile
# Ensure USER is set before CMD/ENTRYPOINT
grep "^USER" Dockerfile
# Verify HEALTHCHECK is defined for services
grep "^HEALTHCHECK" Dockerfile
# Count RUN commands (>5 suggests combination opportunity)
grep -c "^RUN" Dockerfile
# Verify cache cleanup in same RUN layer
grep "rm -rf /var/lib/apt/lists" Dockerfile
grep "--no-cache" Dockerfile # for apkNon-Obvious Checks (project-specific):
| Category | Non-Obvious Convention |
|---|---|
| Base Images | Prefer digest pinning (FROM alpine@sha256:…) over version tags for reproducible builds |
| Layer Ordering | COPY dependency manifests before source code so edits don't bust the install cache |
| Cache Cleanup | Must happen in the same RUN layer as the install; a separate RUN rm -rf … creates a new layer that doesn't reduce size |
| Multi-Stage | Named stages (AS build) allow selective --target build for CI debugging without exposing secrets in final image |
| Secrets | BuildKit --mount=type=secret avoids secrets ever appearing in any layer, including intermediate ones |
Optimization Categories:
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"]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
# Good: Combined RUN (single layer)
RUN apt-get update && apt-get install -y --no-install-recommends \
curl \
git \
&& rm -rf /var/lib/apt/lists/*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# Check if .dockerignore exists
if [ ! -f .dockerignore ]; then
echo "WARNING: .dockerignore file not found"
fiCommon patterns to include:
.git
.gitignore
.env
*.log
node_modules
Dockerfile*
docker-compose*.ymlThe validation script automatically installs tools if not found. No manual installation required.
For permanent installations:
# hadolint
brew install hadolint # macOS
wget -O ~/.local/bin/hadolint https://github.com/hadolint/hadolint/releases/latest/download/hadolint-Linux-x86_64 && chmod +x ~/.local/bin/hadolint # Linux
# Checkov
pip3 install checkovMinimum Versions: hadolint >= 2.12.0 | Checkov: latest | Python >= 3.8
Testing Auto-Install:
# Force temporary installation for testing
FORCE_TEMP_INSTALL=true bash scripts/dockerfile-validate.sh DockerfileWhen tools are not installed, the script auto-installs them temporarily. If auto-install fails:
brew install hadolint (macOS) or wget from GitHub releases (Linux)pip3 install checkovTool Priority:
| Error | Solution |
|---|---|
FROM instruction must be first non-comment | Move ARG VERSION=18 before FROM node:${VERSION} |
| Unknown instruction (typo) | Check spelling: common typos are RUNS, COPIES, FRUM |
| Chained RUN command fails | Use apt-get install -y package || exit 1 or set -e |
COPY failed: file not found | Check path is relative to build context; verify not excluded by .dockerignore |
| Hardcoded secrets detected | Use BuildKit secrets: docker build --secret id=api_key,src=api_key.txt instead of ENV API_KEY=secret123 |
| Slow builds | Optimize layer caching (COPY package files first), use .dockerignore, enable BuildKit (export DOCKER_BUILDKIT=1), use multi-stage builds |
bash scripts/dockerfile-validate.sh [Dockerfile]| File | Purpose |
|---|---|
good-example.Dockerfile | 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 |
| File | Contents |
|---|---|
docker_best_practices.md | Official Docker best practices; full hadolint DL/SC rule listings |
optimization_guide.md | Layer optimization and image size reduction techniques |
security_checklist.md | Container security best practices; full CKV_DOCKER_* check listings |
Follow these steps in order for every validation request:
bash scripts/dockerfile-validate.sh <Dockerfile> to run all 4 stages.Summarize findings by severity:
Propose specific fixes — Use the Read tool to load appropriate reference files before proposing fixes:
| Issue Type | Reference File |
|---|---|
| Security issues (secrets, USER, ports) | references/security_checklist.md |
| Size/performance optimization | references/optimization_guide.md |
| General best practices | references/docker_best_practices.md |
Offer to apply fixes — Ask the user if they want fixes applied, then apply if approved.
Example interaction:
User: "Validate my Dockerfile"
1. Read the Dockerfile using Read tool
2. Run: bash scripts/dockerfile-validate.sh Dockerfile
3. Review output from all 4 stages
4. Summarize findings 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 from reference content
7. Ask: "Would you like me to apply these fixes?"
8. Apply fixes if user approvesFor multi-Dockerfile projects: find all Dockerfile* files, validate each sequentially, aggregate results, and provide a unified report with project-wide improvement suggestions.
Official Docker Documentation:
Security Guidelines:
Best Practices Resources:
Install with Tessl CLI
npx tessl i pantheon-ai/dockerfile-validator@0.1.0