Creating Dockerfiles can be more challenging than it initially seems. You could encounter issues with YAML indentation, inappropriate image usage, or incorrect volume mapping; the process is prone to pitfalls. Writing Dockerfiles often involves navigating through a seemingly straightforward syntax that, in reality, has its share of nuances. When working collaboratively on complex Dockerfiles, sticking to the best practices becomes crucial to avoid potential complications.
Misconfiguring Docker containers can result in a lot of problems—sluggish releases, high storage costs, and frustrated developers. The repercussions extend beyond operational inefficiencies and security concerns. A recent report highlights the vulnerability of Docker instances, revealing that half of new deployments face attacks within a remarkably short time frame.
Therefore it is important to maintain small, secure, efficient, and easily manageable Docker images. One of the most popular and powerful tools for Dockerfile linting is Hadolint. Hadolint is a Dockerfile linter that ensures adherence to best practices. Using Hadolint in your projects becomes a proactive measure, mitigating risks and contributing to the seamless deployment of Docker containers.
Using Hadolint can bring many benefits to your Dockerfile development, such as:
- Improving the security of your Docker images by avoiding common vulnerabilities and risks
- Enhancing the performance of your Docker images by reducing their size and build time
- Increasing the readability and maintainability of your Dockerfiles by following consistent and clear conventions
- Integrating with other tools and platforms to automate and streamline your Dockerfile linting workflow
In this article, I will provide a comprehensive guide to Dockerfile linting with Hadolint. We will cover how to install and use Hadolint, how to configure and customize Hadolint rules and settings, and how to integrate Hadolint with other tools, such as editors, CI/CD pipelines, or code quality platforms.
Installation and Usage
Hadolint is available in different formats for different operating systems. You can choose to install Hadolint as a binary, a Docker image, or a web interface.
- Binary: You can download the latest pre-compiled binary for your operating system from the project’s GitHub releases page. For Linux and Mac, you can also use wget, brew, or scoop to install Hadolint. For example, to install Hadolint on Linux using wget, you can run the following commands:
$ wget -O hadolint
$ sudo mv hadolint /usr/local/bin/hadolint
$ sudo chmod +x /usr/local/bin/hadolint
To check if Hadolint is installed, you can run
- Docker image: You can also use Hadolint as a Docker image without installing it on your system. You can pull the image from Docker Hub using the command:
$ docker pull hadolint/hadolint
To use the image, you can pipe the contents of your Dockerfile into a Hadolint container using the command:
$ docker run --rm -i hadolint/hadolint < Dockerfile
- Web interface: If you don’t want to install or use Hadolint locally, you can access it via the web interface. You can paste your Dockerfile in the text box and see the results instantly.
To lint a Dockerfile using Hadolint, you can pass the path to the Dockerfile as an argument to the Hadolint command. For example, to lint a Dockerfile in the current directory, you can run:
$ hadolint Dockerfile
If you are using the Docker image, you can pipe the Dockerfile to the container as shown above.
The output of Hadolint will show the list of issues it finds in your Dockerfile, along with the severity level and the rule name. For example, the output may look like this:
Dockerfile:3 DL3008 Pin versions in apt get install. Instead of `apt-get install <package>` use `apt-get install <package>=<version>`
Dockerfile:5 SC2086 Double quote to prevent globbing and word splitting.
The output format consists of four parts:
- The file name and the line number where the issue is found
- The rule name that is violated, prefixed with either HL or SC. HL rules are part of Hadolint, while SC rules come from ShellCheck.
- The severity level of the issue, which can be Error, Warning, Style, or Info.
- The description of the issue and the suggestion for improvement.
You can use the output to identify and fix the problems in your Dockerfile and make it more secure, efficient, and readable.
Configuration and Customization
Hadolint is configured via a
.hadolint.yaml file. It will search multiple locations including your working,
.config, and home directories. Only the first found file is used – there’s no merging between locations. The config file lets you customize your scans by ignoring rules and changing their severities.
To ignore a rule, you can add it to the
ignored key in the config file, such as:
This will ignore the rules DL3006 (Always tag the version of an image explicitly) and SC2086 (Double quote to prevent globbing and word splitting) in all scans.
To change the severity of a rule, you can add it to the
override key in the config file, such as:
This will change the severity of DL3008 (Pin versions in apt get install) to error and DL3045 (Avoid
ADD instructions, use
COPY instead) to info.
You can also ignore or override specific rules using inline comments or environment variables. To disable a rule on a specific line, use a comment in one of the following formats:
FROM ubuntu:latest # hadolint ignore=DL3006
RUN apt-get update && apt-get install -y python # hadolint ignore=DL3008,DL3009
This will disable the rules DL3006 and DL3008 on the first line, and DL3008 and DL3009 (Delete the apt-get lists after installing something) on the second line.
To disable a rule for the entire file, use a comment at the top of the file, such as:
# hadolint ignore=DL3006
This will disable the rule DL3006 for the whole file.
To disable a rule using an environment variable, set the variable
HADOLINT_IGNORE to a comma-separated list of rule codes, such as:
This will disable the rules DL3006 and DL3008 for all scans.
You can also use environment variables to change the severity of rules, using the variables
HADOLINT_STYLE, such as:
This will change the severity of DL3008 to error and DL3045 to info for all scans.
Hadolint includes many convenient integrations for automatically running the linter throughout the development process. Some of the most popular ones are:
- VS Code: run Hadolint directly in your editor
- pre-commit: run Hadolint on every git commit
- GitHub Actions: run Hadolint in GitHub CI/CD
- GitLab CI: run Hadolint in GitLab CI/CD
You can find more integrations and detailed instructions on how to use them in the Hadolint documentation.
In this article, we have learned how to use Hadolint for Dockerfile linting. We have seen how Hadolint can help us to write better Dockerfiles by checking and validating the syntax, structure, and content of our Dockerfiles. We have also learned how to install and use Hadolint, how to configure and customize Hadolint rules and settings, and how to integrate Hadolint with other tools and platforms.
Using Hadolint can bring many benefits to our Dockerfile development, such as improving the security, performance, and readability of our Docker images. It can also help us to follow best practices and coding standards, and to avoid common issues and errors.
- Hadolint GitHub repository: The source code and documentation of Hadolint
- Hadolint rules: The list and explanation of all the rules supported by Hadolint
- ShellCheck: The tool that Hadolint uses to validate inline bash
- Dockerfile best practices: The official guide from Docker on how to write Dockerfiles