Introduction
Hadolint catches Dockerfile anti-patterns before they become bloated images or security holes. It parses each Dockerfile into an AST, applies over 30 built-in rules, and delegates shell analysis in RUN instructions to ShellCheck for deep script-level feedback.
What Hadolint Does
- Parses Dockerfiles into an AST for structural rule checking
- Embeds ShellCheck to lint shell commands inside RUN instructions
- Reports rule violations with severity levels and stable rule IDs (DL/SC codes)
- Supports inline ignore comments to suppress specific rules per line
- Outputs results in multiple formats: tty, JSON, SARIF, CodeClimate
Architecture Overview
Hadolint is written in Haskell and compiles to a single static binary. The parser builds a typed AST from each Dockerfile instruction, then a rule engine walks the tree applying best-practice checks. For RUN instructions, the shell script is extracted and piped through an embedded ShellCheck analysis pass.
Self-Hosting & Configuration
- Distribute as a single binary, Docker image, or VS Code extension
- Configure ignored rules and trusted registries in
.hadolint.yaml - Set severity thresholds to fail CI only on warnings or errors
- Integrates with GitHub Actions, GitLab CI, and pre-commit hooks
- Override base image pinning rules with an allowed registries list
Key Features
- Single static binary with zero runtime dependencies
- ShellCheck integration catches bash pitfalls inside RUN instructions
- Stable rule IDs (DL3000-series) make it easy to track and suppress
- SARIF output plugs directly into GitHub Code Scanning
- Runs in under a second on most Dockerfiles, ideal for pre-commit
Comparison with Similar Tools
- docker build --check — basic syntax validation only, no best-practice rules
- Dockle — scans built images for CIS benchmarks, not Dockerfile source
- Trivy — vulnerability scanner for images, not a Dockerfile linter
- dockerfile-lint — Node.js based, fewer rules, no ShellCheck integration
- Semgrep — general static analysis, requires custom Dockerfile rules
FAQ
Q: Can I ignore a specific rule on one line?
A: Yes. Add # hadolint ignore=DL3008 above the instruction to suppress that rule for that line only.
Q: Does Hadolint support multi-stage builds? A: Yes. It tracks build stages and validates COPY --from references and per-stage best practices.
Q: How do I integrate Hadolint into GitHub Actions?
A: Use the official hadolint/hadolint-action which runs the linter and posts annotations on pull requests.
Q: Is Hadolint actively maintained? A: Yes. The project has 12,000+ stars and regular releases adding new rules for recent Docker features.