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
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
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.
There's really only two things you can configure about
hadolintand 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"
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 CI
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
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.
Feb 15, 2021 · 10 min read
Publishing Docker images is a common CI/CD task, and the flexibility CircleCI offers makes it a great tool for the job.
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!