Estimated reading time: 9 minutes
Last updated on October 25th, 2024 at 02:14 pm
Think of Dockerfiles as your building blueprint for creating Docker images. Adding linting to this process, you catch errors early and stick to best practices.
Why bother? Misconfigured Docker containers can be a headache – slow, heavy, and a pain for developers.
Hadolint is the best Dockerfile linter tool that can parse and analyze your Dockerfile
and provide output that doesn’t match best practices per the Docker Guideline.
Dive into this comprehensive guide on linting Dockerfile.
DevOps Efficiency Hacks in Your Inbox! 📩
Stop wasting time searching. Get weekly tips & tutorials to streamline your DevOps workflow.
Table of Contents
What is Hadolint?
Hadolint, an open-source and smart Dockerfile
linter created with Haskell to ensure your Dockerfiles follow the best practices. Following the best practices makes efficient Docker images meaning faster builds and smaller image sizes.
It parses your Dockerfile into an abstract syntax tree AST, it also uses ShellCheck – A shell script static analysis tool to lint bash/sh code in the Dockerfile.
How to build Docker Image 39x times faster?
How to install Hadolint
Hadolint provides an easy-to-use CLI for all platforms. You can download the binaries for Linux, Mac, and Windows.
Install on Linux 🐧
You can install Hadolint in your Linux by following the below steps:
Download the latest binary from the Official GitHub Release
wget -O hadolint https://github.com/hadolint/hadolint/releases/download/v2.12.0/hadolint-Linux-x86_64
Once your downloading is finished, let’s move it to /usr/local/bin
where we install third-party apps.
sudo mv hadolint /usr/local/bin/
Lastly, provide the execution permission
sudo chmod +x /usr/local/bin/hadolint
Install on Mac 🍎
You can install it on Mac using brew
brew install hadolint
Install on Windows 🪟
You can download the binary for Windows or use Scoop – a command-line installer for Windows.
scoop install hadolint
If you’re using Chocolatey – a package manager for Windows for installation, there’s a GitHub issue open for support.
Verify the installation
Let’s confirm the installation was successful
hadolint -v
Haskell Dockerfile Linter 2.12.0
How to Lint Dockerfile Using Hadolint
Using it is straightforward: once you install it on your system, run the command with your Dockerfile.
Let’s write a sample Dockerfile
that isn’t optimized yet.
nano Dockerfile
Save the following content:
FROM ubuntu:latest
MAINTAINER [email protected]
LABEL org.website="test.com"
COPY requirements.txt requirements.txt
RUN pip install --upgrade pip
RUN pip install -r requirements.txt
COPY . code
WORKDIR /code
EXPOSE 8080
CMD python manage.py runserver 0.0.0.0:8080
Let’s run the linting with the above Dockerfile
.
hadolint Dockerfile
Dockerfile:1 DL3007 warning: Using latest is prone to errors if the image will ever update. Pin the version explicitly to a release tag
Dockerfile:2 DL4000 error: MAINTAINER is deprecated
Dockerfile:5 DL3003 warning: Use WORKDIR to switch to a directory
Dockerfile:5 SC2164 warning: Use 'cd ... || exit' or 'cd ... || return' in case cd fails.
Dockerfile:7 DL3045 warning: `COPY` to a relative destination without `WORKDIR` set.
Dockerfile:9 DL3042 warning: Avoid use of cache directory with pip. Use `pip install --no-cache-dir <package>`
Dockerfile:9 DL3059 info: Multiple consecutive `RUN` instructions. Consider consolidation.
Dockerfile:12 DL3045 warning: `COPY` to a relative destination without `WORKDIR` set.
Dockerfile:17 DL3025 warning: Use arguments JSON notation for CMD and ENTRYPOINT arguments
That’s a lot of information in the output. Let’s break down what it means.
It parses your Dockerfile against a predefined set of rules line by line and for every violation provides the following structured output:
<LINE_NUMBER><RULE_CODE><SEVERITY_LEVEL>: <DESCRIPTION>
Let’s understand in detail.
Line Number
Provide the exact line number where the rule is violated. The below output shows that line number #1 has an issue:
Dockerfile:1 DL3007 warning: Using latest is prone to errors if the image will ever update. Pin the version explicitly to a release tag
Rule Code
From the output, you can check it is prefixed with DL
or SC
Dockerfile:5 DL3003 warning: Use WORKDIR to switch to a directory
Dockerfile:5 SC2164 warning: Use 'cd ... || exit' or 'cd ... || return' in case cd fails.
Rule Code and Meaning
Rule Code | Prefix | Description |
---|---|---|
DL3003 | DL | This means it comes from Linter. |
SC2164 | SL | This means it comes from SpellCheck – A shell script static analysis tool, |
You can find the detailed documentation for each of the rules including the information and how to fix it. For instance, warning DL303 you can find the documentation here.
Severity Level
Not all rules are treated equally, some rules are more important than others. The severity level shows how critical a rule violation is.
It categorizes severity levels into six levels: error, warning, info, style, ignore, and none.
Dockerfile:9 DL3059 info: Multiple consecutive `RUN` instructions. Consider consolidation.
For instance, Info is just informational, style suggests improvements.
You can also exclude severity levels that cause a failure by using the additional CLI option such as--failure-threshold
( shortcut -t
). Remember that violated rules will still be reported but not cause failure.
Let’s modify the command to only fail on error
violation not on info
or warning
:
hadolint --failure-threshold error Dockerfile
hadolint -t error Dockerfile
How to Ignore Rules in Hadolint
Following best practices is recommended, there might be cases where you want to ignore specific rules. It provides the flexibility to ignore one or more rules using the CLI option --ignore [RULECODE]
Let’s ignore the rule DL3059
by running the command:
hadolint --ignore DL3059 Dockerfile
You can ignore multiple rules by adding the same --ingore [RULECODE]
hadolint --ignore DL3059 --ignore DL3003 Dockerfile
Well, this approach is good for quick easy fixes but adding more rules makes it troublesome.
There’s a more easy and maintainable way to ignore such rules inline Dockerfile
. You can exclude specific rules on a line-to-line basis by adding a comment:
# hadolint ignore=DL3007
FROM ubuntu:latest
Level Up Your DevOps Skills! 📈
Get Weekly Tips, Tutorials & Master the Latest Trends – Subscribe Now!
Customize Output Format for Hadolint
It supports various output format options (the default option is tty), this is very helpful especially when you want to integrate with other tools such as API and CI/CD pipeline.
You can customize the output format with the CLI option --format
:
hadolint --format json Dockerfile
Below is the list of supported output formats:
json
– Provide the output in JSON structure format which can be used with API or scripts.checkstyle
– Generate Checkstyle supported report.codeclimate
– Generate Code Climate supported the report.gitlab_codeclimate
– Works with the GitLab Code Quality feature. You can integrate with Gitlab CI for linting Pull Request.codacy
– Generate Codacy-supported report.
Use this output format with your CI/CD pipeline.
Configuration file with Hadolint
Manually providing all the options every time you run the linting can be troublesome. You can simplify this process by adding all the options in a single configuration file named hadolint.yml
Configuration files can be used globally or project-specific. It will check the configuration file for the below folders:
$PWD/.hadolint.yaml
$XDG_CONFIG_HOME/hadolint.yaml
$HOME/.config/hadolint.yaml
$HOME/.hadolint/hadolint.yaml or $HOME/hadolint/config.yaml
$HOME/.hadolint.yaml
You can create a single configuration file and put it in the root of your repository, this way you can have consistency in writing the Dockerfile across the teams. By using this approach you can create a standardized practice that can be shared with developers and DevOps engineers.
You can check the Configuration Documentation for all the available configuration options.
Let’s create a hadolint.yml
file with sample configuration:
failure-threshold: error
format: json
ignored:
- DL3059
- DL3003
strict-labels: false
In addition to the config file, you can also environment variables to configure it:
NO_COLOR=1
HADOLINT_NOFAIL=1
HADOLINT_VERBOSE=1
HADOLINT_FORMAT=json
HADOLINT_FAILURE_THRESHOLD=error
HADOLINT_IGNORE=DL3059,DL3003
HADOLINT_STRICT_LABELS=1
Let’s use the hadolint.yml
config file:
hadolint --config hadolint.yml Dockerfile
Hadolint Integration with CICD Pipeline
Integrating within the CI/CD pipeline ensures the code quality from the start. By catching errors early in the pipeline you can streamline the process and follow the best practices.
Your CI/CD flow will look like the below:
- Docker Build CI Pipeline:
- Include Hadolint in your Docker Build Pipeline.
- Whenever a new Pull Request is raised, the pipeline will automatically check for the lining issues
- Prompt Feedback for Developer:
- If the
Dockerfile
doesn’t match the defined standards, the build fails. - The developer can check the raised issues from the linting and fix them.
- If the
- Customize Configuration:
- Define the custom hadolint.yml configuration that follows the organization’s standards.
It provides the out-of-the-box integration for the various tools:
- VS Code Hadolint Extension – Run linting in your code editor
- pre-commit – Git pre-commit hooks
- GitHub Actions – Run with the GitHub CI/CD
- GitLab CI – Run with the Gitlab CI
Check out all the supported integrations.
Lint Dockerfile with Online Hadolint
You can try out the online version without installing anything in your system. This can be helpful for quickly testing your Dockerfile to prevent CI/CD failure.
Quickly try out the Online Hadolint from here.
Run Hadolint as a Docker Container
If you don’t want to install anything on your machine, another way to lint your Dockerfile is to run it as a container version. The prerequisite is you should have Docker installed ( I believe you do ).
You can run the below command to start the disposable Hadolint container:
docker run --rm -i ghcr.io/hadolint/hadolint < Dockerfile
This will work the same way and provide the output, once finished it’ll destroy the container.
Fast-Track Your DevOps Career 🚀
Stay ahead of the curve with the latest industry insights. Get weekly tips & propel your skills to the next level.
Conclusion
Hadolint is a great tool for making sure you’re lining your Docker image anywhere, every time.
Incorporating a linter into the workflow ensures our Dockerfiles are always readable, understandable, and maintainable whether in the cloud or on your local machine.
Key takeaway:
- Easy to manage workflow by adding Linting into day-to-day development.
- Build a small, fast, and secure Docker image.
- Linting everywhere – Wherever you build your Dockerfile—on your laptop, in the cloud, or in CI pipelines—linting happens consistently.
This blog gives you a comprehensive guide using the Hadolint for lining Dockerfile. If you want to learn more about how to build your Dockerfile 39x faster, check our recent post on Docker Build 39x Times Faster: Docker Build Cloud.
If you’re looking for how to make your Docker container secure check out the Docker Container Security Cheatsheet and don’t get hacked🔐