Dockerfiles look simple and are full of subtle foot-guns: unpinned base image tags, package installs that leave caches behind, running as root, ordering that busts the build cache. Hadolint is a linter that catches all of it. It parses your Dockerfile, applies a set of best-practice rules, and even runs the embedded shell commands through ShellCheck - so the mistakes that make images bloated, insecure, or non-reproducible get flagged before you ever run a build.
Best Practices, Enforced
Run it against a Dockerfile and it reports the issues with rule codes:
# Lint a Dockerfile
hadolint Dockerfile
# It flags things like:
# FROM image without a pinned tag
# apt-get install without --no-install-recommends
# running as root, cache-busting layer order
ShellCheck Built In
Because so many Dockerfile bugs live in the RUN lines, Hadolint pipes those through ShellCheck automatically - so a broken shell command in a build step is caught by the same tool. Rules can be ignored per-line or per-project when you have a reason, and it slots neatly into CI.
Rough Edges and Limitations
- Style and safety, not correctness. It enforces good practice; it can't tell whether your image does what you intend.
- Opinionated defaults. Some rules won't fit every project and need suppressing.
- Dockerfile-scoped. It lints the file, not the resulting image - pair it with an image analyzer.
For anyone writing Dockerfiles, Hadolint is a cheap way to keep them lean, secure, and reproducible from the start.
Internal link suggestion: link "pair it with an image analyzer" to the dive post, which inspects the built image's layers.