Dockerfile security linting and best practice validation using Hadolint with 100+ built-in rules aligned to CIS Docker Benchmark. Use when: (1) Analyzing Dockerfiles for security misconfigurations and anti-patterns, (2) Enforcing container image security best practices in CI/CD pipelines, (3) Detecting hardcoded secrets and credentials in container builds, (4) Validating compliance with CIS Docker Benchmark requirements, (5) Integrating shift-left container security into developer workflows, (6) Providing remediation guidance for insecure Dockerfile instructions.
Dockerfile security linting and best practice validation using Hadolint with 100+ built-in rules aligned to CIS Docker Benchmark. Use when: (1) Analyzing Dockerfiles for security misconfigurations and anti-patterns, (2) Enforcing container image security best practices in CI/CD pipelines, (3) Detecting hardcoded secrets and credentials in container builds, (4) Validating compliance with CIS Docker Benchmark requirements, (5) Integrating shift-left container security into developer workflows, (6) Providing remediation guidance for insecure Dockerfile instructions.
Hadolint is a Dockerfile linter that validates container build files against security best practices and the CIS Docker Benchmark. It analyzes Dockerfile instructions to identify misconfigurations, anti-patterns, and security vulnerabilities before images are built and deployed.
Hadolint integrates ShellCheck to validate RUN instructions, ensuring shell commands follow security best practices. With 100+ built-in rules mapped to CIS Docker Benchmark controls, Hadolint provides comprehensive security validation for container images.
Quick Start
Install Hadolint
# macOS via Homebrew
brew install hadolint
# Linux via binary
wget -O /usr/local/bin/hadolint https://github.com/hadolint/hadolint/releases/latest/download/hadolint-Linux-x86_64
chmod +x /usr/local/bin/hadolint
# Via Docker
docker pull hadolint/hadolint
Scan Dockerfile
# Scan Dockerfile in current directory
hadolint Dockerfile
# Scan with specific Dockerfile path
hadolint path/to/Dockerfile
# Using Docker
docker run --rm -i hadolint/hadolint < Dockerfile
Generate Report
# JSON output for automation
hadolint -f json Dockerfile > hadolint-report.json
# GitLab Code Quality format
hadolint -f gitlab_codeclimate Dockerfile > hadolint-codeclimate.json
# Checkstyle format for CI integration
hadolint -f checkstyle Dockerfile > hadolint-checkstyle.xml
Core Workflows
1. Local Development Scanning
Validate Dockerfiles during development:
# Basic scan with colored output
hadolint Dockerfile
# Scan with specific severity threshold
hadolint --failure-threshold error Dockerfile
# Show only warnings and errors
hadolint --no-color --format tty Dockerfile | grep -E "^(warning|error)"# Verbose output with rule IDs
hadolint -t style -t warning -t error Dockerfile
Output Format:
Dockerfile:3 DL3008 warning: Pin versions in apt get install
Dockerfile:7 DL3025 error: Use JSON notation for CMD and ENTRYPOINT
Dockerfile:12 DL3059 info: Multiple RUN instructions detected
When to use: Developer workstation, pre-commit validation, iterative Dockerfile development.
2. CI/CD Pipeline Integration
Automate Dockerfile validation in build pipelines:
When to use: Automated security gates, pull request checks, deployment validation.
3. Configuration Customization
Create .hadolint.yaml to customize rules:
# .hadolint.yamlfailure-threshold:warningignored:-DL3008# Allow unpinned apt-get packages (assess risk first)-DL3059# Allow multiple RUN instructionstrustedRegistries:-docker.io/library# Official Docker Hub images-gcr.io/distroless# Google distroless images-registry.access.redhat.com# Red Hat registryoverride:error:-DL3001# Enforce: never use yum/dnf/zypper without version pinswarning:-DL3015# Warn: use --no-install-recommends with apt-getinfo:-DL3059# Info: multiple RUN instructions reduce layer cachinglabel-schema:maintainer:textorg.opencontainers.image.vendor:textorg.opencontainers.image.version:semver
Security Dashboards: Export JSON to Grafana, Kibana, Datadog for centralized monitoring
SDLC Integration
Development: Pre-commit hooks provide immediate feedback
Code Review: PR checks prevent insecure Dockerfiles from merging
Testing: Scan test environment Dockerfiles
Staging: Validation gate before production promotion
Production: Periodic audits of deployed container configurations
Troubleshooting
Issue: Too Many False Positives
Symptoms: Legitimate patterns flagged (legacy Dockerfiles, specific use cases)
Solution:
# Create .hadolint.yamlignored:-DL3059# Multiple RUN instructions (valid for complex builds)# Or use inline ignores# hadolint ignore=DL3008RUNapt-getupdate&&apt-getinstall-ycurl
Consult references/remediation_guide.md for rule-specific guidance.
Issue: Base Image Registry Not Trusted
Symptoms: Error about untrusted registry even for legitimate images
Solution:
# Add to .hadolint.yamltrustedRegistries:-mycompany.azurecr.io-gcr.io/my-project-docker.io/library
Issue: ShellCheck Warnings in RUN Instructions
Symptoms: SC2086, SC2046 warnings from ShellCheck integration
Solution:
# Bad: Unquoted variables
RUN echo $MY_VAR > file.txt
# Good: Quoted variables
RUN echo "$MY_VAR" > file.txt
# Or disable specific ShellCheck rule
# hadolint ignore=DL4006
RUN echo $MY_VAR > file.txt
See references/shellcheck_integration.md for complete ShellCheck guidance.
Issue: Multi-Stage Build Not Recognized
Symptoms: Errors about missing USER instruction despite proper multi-stage setup
Solution:
# Ensure each stage has appropriate USER
FROM node:18 AS builder
# Build operations...
FROM node:18-alpine AS runtime
USER node # Add USER in final stage
CMD ["node", "app.js"]
Issue: CI Pipeline Failing on Warnings
Symptoms: Build fails on low-severity issues
Solution:
# Adjust failure threshold in CI
hadolint --failure-threshold error Dockerfile
# Or configure per-environmentif [ "$CI_ENVIRONMENT" == "production" ]; then
hadolint --failure-threshold warning Dockerfile
else
hadolint --failure-threshold error Dockerfile
fi
Advanced Configuration
Custom Rule Severity Override
# .hadolint.yamloverride:error:-DL3001# Package versioning is critical-DL3020# COPY vs ADD is security-criticalwarning:-DL3059# Multiple RUN is warning, not infoinfo:-DL3008# Downgrade apt-get pinning to info for dev images
Inline Suppression
# Suppress single rule for one instruction
# hadolint ignore=DL3018
RUN apk add --no-cache curl
# Suppress multiple rules
# hadolint ignore=DL3003,DL3009
WORKDIR /tmp
RUN apt-get update && apt-get install -y wget
# Global suppression (use sparingly)
# hadolint global ignore=DL3059
Trusted Registry Enforcement
# .hadolint.yamltrustedRegistries:-docker.io/library# Official images only-gcr.io/distroless# Google distroless-cgr.dev/chainguard# Chainguard images# This will error on:# FROM nginx:latest ❌ (docker.io/nginx)# FROM docker.io/library/nginx:latest ✅ (trusted)