hadolint: Lint a Dockerfile in CI
hadolint parses a Dockerfile and reports DLxxxx best-practice issues plus ShellCheck findings inside RUN lines, exiting 1 on any failure.
hadolint is the standard Dockerfile linter. It checks Docker best practices and runs ShellCheck on shell inside RUN, all in one pass.
What it does
hadolint <Dockerfile> parses the file, applies its DLxxxx rules, and lints embedded shell with ShellCheck (SCxxxx). It exits 1 when any rule at or above the failure threshold triggers, 0 when clean. Read the Dockerfile from stdin with -.
Common usage
hadolint Dockerfile
# from stdin (handy in pipelines)
docker run --rm -i hadolint/hadolint < Dockerfile
# choose an output format
hadolint --format json DockerfileFlags
| Flag | What it does |
|---|---|
| <Dockerfile> | Path to the Dockerfile (or - for stdin) |
| --ignore <rule> | Skip a DL or SC rule (repeatable) |
| --format <fmt> | Output format (tty, json, checkstyle, gcc, sarif) |
| --failure-threshold <sev> | Minimum severity that fails the run |
| --no-fail | Always exit 0 (report only) |
| --trusted-registry <reg> | Allow FROM only from these registries |
In CI
The hadolint/hadolint Docker image keeps the linter version pinned and reproducible across runners. Use --format gcc or sarif so findings annotate the PR or feed code scanning instead of sitting in the log.
Common errors in CI
"DL3008 Pin versions in apt get install" and "DL3018 Pin versions in apk add" are the most common failures; pin or ignore them deliberately. "Error: Cannot parse ..." means an invalid Dockerfile (often a heredoc or syntax hadolint does not support yet). A non-zero exit with no visible findings means the failure-threshold caught a low-severity rule.