Photo by Rob Coates on Unsplash
Linters don't just enforce style guidelines, they also catch potential issues. hadolint
(Haskell Dockerfile Linter) is the most popular linter for Dockerfiles, and it's incredibly easy to use.
hadolint
parses your Dockerfiles into an abstract syntax tree and then checks rules on that tree. Not only does it have its own rules specific to Dockerfiles, it also uses ShellCheck to lint RUN
instructions.
Usage
Assuming you already have Docker installed because we're talking about Dockerfiles, the easiest way to run hadolint
is with Docker:
docker run --rm --interactive hadolint/hadolint < Dockerfile
Where Dockerfile
is a file that exists in your working directory, outside of the container.
There are some other ways to install hadolint
, but running it from Docker is probably the easiest way to go.
Configuration
There are really only two things you can configure about hadolint
:
- What
hadolint
and ShellCheck rules to ignore - What container registries are "trusted"
Both of those can be configured in a $PWD/.hadolint.yaml
file like so:
ignored:
- DL3003
- DL3018
trustedRegistries:
- docker.io
Or you can inline-configure ignored rules like so:
# hadolint ignore=DL3007
FROM alpine:latest
# hadolint ignore=DL3003,DL3018
RUN apk --update add --no-cache git && \
cd "$(mktemp -d)" && \
git pull "https://github.com/hadolint/hadolint.git"
Example output
Taking the above example and removing the ignored rules:
FROM alpine:latest
RUN apk --update add --no-cache git && \
cd "$(mktemp -d)" && \
git pull "https://github.com/hadolint/hadolint.git"
Here's the example output:
$ docker run --rm --interactive hadolint/hadolint < Dockerfile
/dev/stdin:1 DL3007 Using latest is prone to errors if the image will ever update. Pin the version explicitly to a release tag
/dev/stdin:3 DL3003 Use WORKDIR to switch to a directory
/dev/stdin:3 DL3018 Pin versions in apk add. Instead of `apk add <package>` use `apk add <package>=<version>`
Adding to CircleCI
Linters become a lot more powerful when you add them to your CI pipeline. A linter without enforcement will surely be ignored over time.
Here's a sample of how you could add hadolint
to a CircleCI .circleci/config.yml
:
version: 2.1
executors:
docker:
docker:
- image: docker:stable
jobs:
lint:
executor: docker
steps:
- checkout
- setup_remote_docker
- run:
name: Run hadolint
command: docker run --rm --interactive hadolint/hadolint < Dockerfile
workflows:
version: 2
test:
jobs:
- lint
See "Publishing Docker Images with CircleCI" for a more complete guide on using CircleCI to publish Docker images.
Publishing Docker Images with CircleCI
Feb 15, 2021 · 8 min read
Publishing Docker images is a common CI/CD task, and the flexibility CircleCI offers makes it a great tool for the job.
Conclusion
Linters are a great tool to prevent team arguments over style, but they're a great tool for preventing potential errors - start using hadolint
with your Dockerfiles today!