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.