Learn Docker With My Newest Course

Dive into Docker takes you from "What is Docker?" to confidently applying Docker to your own projects. It's packed with best practices and examples. Start Learning Docker →

Docker Tip #89: Lint your Dockerfile with Hadolint


This can help you build images that stick to best practices and save time by detecting errors before you build your images.

If you prefer video, I recorded a demo video going over what’s written below.

Hadolint detects around 100 issues. These range from style choices to errors.

I recently added it to all of my Docker Compose example web app repos and it found a few things like forgetting to use the CMD array syntax in 1 spot, using _ in a label key instead of - (underscores are illegal characters as label keys) and forgetting to set -o pipefail in a RUN instruction when using Unix pipes.

What’s neat is it’s packaged into a Docker image so you don’t need to install anything locally to run it, although you can brew install it as well as find it in other package managers.

Here’s how I’ve been running it as a Docker container:

docker container run --rm -i hadolint/hadolint hadolint --ignore DL3008 - < Dockerfile

In this case it’ll lint a Dockerfile in the directory where you run the command.

Rule DL3008 is related to version pinning all of your apt package versions in your Dockerfile. Personally I don’t think that’s worth it since your distro will lock those versions and ideally you would want security patches to be updated as you re-build your images periodically. A full list of rules can be found in hadolint’s documentation.

If you’re curious, it uses ShellCheck to lint your RUN instructions which is fantastic.

If you find yourself wanting to customize hadolint a bit it does support the idea of a config file which you can volume mount into hadolint’s container when you run it. I haven’t used this since the default settings are solid minus that one rule I ignored.

I have hadolint running in CI to help detect issues automatically. This is one case where I like avoiding a specific image version and use latest because as hadolint gets updated, it may add new rules. I like this because I re-build my images on a schedule and I want CI to break if my images aren’t sticking to current best practices.

If you want CI to stick to using the same Dockerized version of hadolint you can always use a specific version. A list of tags are available on the Docker Hub.

Free Intro to Docker Email Course

Over 5 days you'll get 1 email per day that includes video and text from the premium Dive Into Docker course. By the end of the 5 days you'll have hands on experience using Docker to serve a website.