ConfigsApr 16, 2026·3 min read

Hadolint — Dockerfile Best Practice Linter

A smart Dockerfile linter that parses Dockerfiles into an AST and checks them against proven best-practice rules, integrating ShellCheck for RUN instruction analysis.

TL;DR
Hadolint catches Dockerfile anti-patterns by parsing them into an AST and applying ShellCheck.
§01

What it is

Hadolint is a smart Dockerfile linter that parses Dockerfiles into an abstract syntax tree and validates them against proven best-practice rules. It integrates ShellCheck to analyze the shell commands inside RUN instructions, catching both Dockerfile structure issues and shell scripting mistakes in a single pass.

Hadolint is aimed at DevOps engineers, platform teams, and anyone building container images who wants to catch misconfigurations before they reach production. It runs as a standalone binary, a Docker container, or a CI check.

§02

Why it saves time or tokens

Dockerfile mistakes like missing --no-cache on apt-get, using latest tags, or running as root are easy to miss in review but expensive in production. Hadolint catches them automatically. When AI assistants generate Dockerfiles, running Hadolint on the output validates correctness without a human reading every line, reducing the iteration tokens needed to get a working image.

§03

How to use

  1. Install Hadolint: download the binary from GitHub releases, or run docker pull hadolint/hadolint
  2. Lint a Dockerfile: hadolint Dockerfile
  3. Integrate into CI by adding Hadolint as a step in your GitHub Actions, GitLab CI, or Jenkins pipeline
§04

Example

# Bad Dockerfile - Hadolint will flag these
FROM ubuntu:latest
RUN apt-get update && apt-get install -y python3
COPY . /app
RUN cd /app && pip install -r requirements.txt

Hadolint output:

DL3007: Using latest is prone to errors
DL3008: Pin versions in apt-get install
DL3003: Use WORKDIR to switch to a directory
DL3042: Avoid cache directory with pip install --no-cache-dir
RuleSeverityFix
DL3007WarningPin base image tag
DL3008WarningPin apt package versions
DL3003WarningUse WORKDIR not cd
DL3042WarningAdd --no-cache-dir to pip
§05

Related on TokRepo

§06

Common pitfalls

  • Hadolint rules can be overly strict for certain base images; use .hadolint.yaml to ignore rules that do not apply to your stack
  • ShellCheck integration only works for bash/sh; RUN instructions using other shells are not analyzed
  • Running Hadolint only locally without CI integration means team members who skip it will push unvalidated Dockerfiles

Frequently Asked Questions

How does Hadolint integrate with CI/CD pipelines?+

Hadolint runs as a single binary or Docker container that exits with a non-zero code when violations are found. Add it as a step in GitHub Actions, GitLab CI, or any pipeline that runs shell commands. Most teams use the official GitHub Action from the Hadolint repository for one-line integration.

Can Hadolint check shell scripts inside RUN instructions?+

Yes. Hadolint embeds ShellCheck internally. When it encounters a RUN instruction, it extracts the shell commands and passes them through ShellCheck analysis. This catches quoting errors, undefined variables, and POSIX compliance issues that a Dockerfile-only linter would miss.

How do I ignore specific Hadolint rules?+

Create a `.hadolint.yaml` file in your project root and list rules under the `ignored` key. You can also inline-ignore a specific rule with a comment `# hadolint ignore=DL3008` above the offending instruction. The config file also supports setting the trusted registries and overriding severity levels.

Does Hadolint support multi-stage Dockerfiles?+

Yes. Hadolint parses the entire Dockerfile including all stages. It validates each FROM instruction, checks that COPY --from references valid stages, and applies rules independently to each build stage. Multi-stage builds are fully supported without additional configuration.

What is the difference between Hadolint and Docker Scout?+

Hadolint is a static linter that checks Dockerfile syntax and best practices before you build. Docker Scout analyzes built images for known vulnerabilities in packages. They are complementary: Hadolint catches structural problems early, while Docker Scout catches CVEs in the resulting image layers.

Citations (3)
  • Hadolint GitHub— Hadolint parses Dockerfiles into an AST and integrates ShellCheck
  • ShellCheck GitHub— ShellCheck is a static analysis tool for shell scripts
  • Docker Docs— Dockerfile best practices for building images

Discussion

Sign in to join the discussion.
No comments yet. Be the first to share your thoughts.

Related Assets