|author||Jose Lorenzo Rodriguez <email@example.com>||Sat Feb 03 13:14:29 2018 +0100|
|committer||Jose Lorenzo Rodriguez <firstname.lastname@example.org>||Sat Feb 03 13:14:29 2018 +0100|
Pin dockerfile versions, but not to the patch version Pinning down to the patch version makes the dockerfile error prone, as apt mirros delete old patch versions from their repos
A smarter Dockerfile linter that helps you build best practice Docker images. The linter is parsing the Dockerfile into an AST and performs rules on top of the AST. It is standing on the shoulders of ShellCheck to lint the Bash code inside
You can run
hadolint locally to lint your Dockerfile.
hadolint <Dockerfile> hadolint --ignore DL3003 --ignore DL3006 <Dockerfile> # exclude specific rules
Docker comes to the rescue to provide an easy way how to run
hadolint on most platforms. Just pipe your
docker run --rm -i hadolint/hadolint < Dockerfile
You can download prebuilt binaries for OSX, Windows and Linux from the latest release page. However, if it doesn't work for you, please fall back to Docker,
brew or source installation.
If you are on OSX you can use brew to install hadolint.
brew install hadolint
git clone https://github.com/hadolint/hadolint cd hadolint stack install
hadolint supports specifying the ignored rules using a configuration file. The configuration file should be in
yaml format. This is one valid configuration file as an example:
ignored: - DL3000 - SC1010
Configuration files can be used globally or per project. By default, hadolint will look for a configuration file in the current directory with the name
The global configuration file should be placed in the folder specified by
XDG_CONFIG_HOME, with the name
hadolint.yaml. In summary, the following locations are valid for the configuration file, in order or preference:
In windows, the
%LOCALAPPDATA% environment variable is used instead of
To get most of
hadolint it is useful to integrate it as a check to your CI or to your editor to lint your
Dockerfile as you write it. See our Integration docs.
An incomplete list of implemented rules. Click on the error code to get more detailed information.
Rules with the prefix
DL originate from hadolint. Take a look at
Rules.hs to find the implementation of the rules.
Rules with the
SC prefix originate from ShellCheck (Only the most common rules are listed, there are dozens more)
Please create an issue if you have an idea for a good rule.
|DL3000||Use absolute WORKDIR.|
|DL3001||For some bash commands it makes no sense running them in a Docker container like ssh, vim, shutdown, service, ps, free, top, kill, mount, ifconfig.|
|DL3002||Do not switch to root USER.|
|DL3003||Use WORKDIR to switch to a directory.|
|DL3004||Do not use sudo as it leads to unpredictable behavior. Use a tool like gosu to enforce root.|
|DL3005||Do not use apt-get upgrade or dist-upgrade.|
|DL3007||Using latest is prone to errors if the image will ever update. Pin the version explicitly to a release tag.|
|DL3006||Always tag the version of an image explicitly.|
|DL3008||Pin versions in apt-get install.|
|DL3009||Delete the apt-get lists after installing something.|
|DL3010||Use ADD for extracting archives into an image.|
|DL3011||Valid UNIX ports range from 0 to 65535.|
|DL3012||Provide an email address or URL as maintainer.|
|DL3013||Pin versions in pip.|
|DL3014||Use the |
|DL3015||Avoid additional packages by specifying --no-install-recommends.|
|DL3016||Pin versions in |
|DL3017||Do not use |
|DL3018||Pin versions in apk add. Instead of |
|DL3019||Use the |
|DL4000||MAINTAINER is deprecated.|
|DL4001||Either use Wget or Curl but not both.|
|SC1007||Remove space after |
|SC1010||Use semicolon or linefeed before |
|SC1018||This is a unicode non-breaking space. Delete it and retype as space.|
|SC1035||You need a space here|
|SC1045||It's not |
|SC1065||Trying to declare parameters? Don't. Use |
|SC1066||Don't use $ on the left side of assignments.|
|SC1068||Don't put spaces around the |
|SC1077||For command expansion, the tick should slant left (` vs ´).|
|SC1078||Did you forget to close this double-quoted string?|
|SC1079||This is actually an end quote, but due to next char, it looks suspect.|
|SC1081||Scripts are case sensitive. Use |
|SC1086||Don't use |
|SC1087||Braces are required when expanding arrays, as in |
|SC1095||You need a space or linefeed between the function name and body.|
|SC1098||Quote/escape special characters when using |
|SC1099||You need a space before the |
|SC2002||Useless cat. Consider cmd < file | .. or cmd file | .. instead.|
|SC2015||Note that A && B || C is not if-then-else. C may run when A is true.|
|SC2026||This word is outside of quotes. Did you intend to ‘nest ‘“‘single quotes’”’ instead’?|
|SC2046||Quote this to prevent word splitting|
|SC2086||Double quote to prevent globbing and word splitting.|
|SC2140||Word is in the form |
|SC2154||var is referenced but not assigned.|
|SC2164||Use cd ... || exit in case |
If you are an experienced Haskeller we would be really thankful if you would tear our code apart in a review.
git clone --recursive email@example.com:hadolint/hadolint.git
Install the dependencies
The easiest way to try out the parser is using the REPL.
# start the repl stack repl # parse instruction and look at AST representation parseString "FROM debian:jessie"
Run unit tests.
Run integration tests.