当前位置: 首页 > 软件库 > 云计算 > >

hadolint

授权协议 GPL-3.0 License
开发语言 Java
所属分类 云计算
软件类型 开源软件
地区 不详
投 递 者 廉飞捷
操作系统 跨平台
开源组织
适用人群 未知
 软件概览

Haskell Dockerfile Linter

Build Statuspipecat

A smarter Dockerfile linter that helps you build best practice Dockerimages. The linter parses the Dockerfile into an AST and performs rules ontop of the AST. It stands on the shoulders of ShellCheck to lintthe Bash code inside RUN instructions.

�� Check the online version onhadolint.github.io/hadolint

How to use

You can run hadolint locally to lint your Dockerfile.

hadolint <Dockerfile>
hadolint --ignore DL3003 --ignore DL3006 <Dockerfile> # exclude specific rules
hadolint --trusted-registry my-company.com:500 <Dockerfile> # Warn when using untrusted FROM images

Docker comes to the rescue, providing an easy way how to run hadolint on mostplatforms.Just pipe your Dockerfile to docker run:

docker run --rm -i hadolint/hadolint < Dockerfile
# OR
docker run --rm -i ghcr.io/hadolint/hadolint < Dockerfile

or using Podman:

podman run --rm -i docker.io/hadolint/hadolint < Dockerfile
# OR
podman run --rm -i ghcr.io/hadolint/hadolint < Dockerfile

or using Windows PowerShell:

cat .\Dockerfile | docker run --rm -i hadolint/hadolint

Install

You can download prebuilt binaries for OSX, Windows and Linux from the latestrelease page. However, if this does not work for you, please fall back tocontainer (Docker), brew or source installation.

On OSX, you can use brew to install hadolint.

brew install hadolint

On Windows, you can use scoop toinstall hadolint.

scoop install hadolint

As mentioned earlier, hadolint is available as a container image:

docker pull hadolint/hadolint
# OR
docker pull ghcr.io/hadolint/hadolint

If you need a container with shell access, use the Debian or Alpinevariants:

docker pull hadolint/hadolint:latest-debian
# OR 
docker pull hadolint/hadolint:latest-alpine
# OR
docker pull ghcr.io/hadolint/hadolint:latest-debian
# OR
docker pull ghcr.io/hadolint/hadolint:latest-alpine

You can also build hadolint locally. You need Haskell and the stackbuild tool to build the binary.

git clone https://github.com/hadolint/hadolint \
&& cd hadolint \
&& stack install

If you want theVS Code Hadolintextension to use Hadolint in a container, you can use the followingwrapper script:

#!/bin/bash
dockerfile="$1"
shift
docker run --rm -i hadolint/hadolint hadolint "$@" - < "$dockerfile"

CLI

hadolint --help
hadolint - Dockerfile Linter written in Haskell

Usage: hadolint [-v|--version] [--no-fail] [--no-color] [-c|--config FILENAME] 
                [-V|--verbose] [-f|--format ARG] [DOCKERFILE...] 
                [--error RULECODE] [--warning RULECODE] [--info RULECODE] 
                [--style RULECODE] [--ignore RULECODE] 
                [--trusted-registry REGISTRY (e.g. docker.io)] 
                [--require-label LABELSCHEMA (e.g. maintainer:text)] 
                [--strict-labels] [-t|--failure-threshold THRESHOLD]
  Lint Dockerfile for errors and best practices

Available options:
  -h,--help                Show this help text
  -v,--version             Show version
  --no-fail                Don't exit with a failure status code when any rule
                           is violated
  --no-color               Don't colorize output
  -c,--config FILENAME     Path to the configuration file
  -V,--verbose             Enables verbose logging of hadolint's output to
                           stderr
  -f,--format ARG          The output format for the results [tty | json |
                           checkstyle | codeclimate | gitlab_codeclimate |
                           codacy] (default: tty)
  --error RULECODE         Make the rule `RULECODE` have the level `error`
  --warning RULECODE       Make the rule `RULECODE` have the level `warning`
  --info RULECODE          Make the rule `RULECODE` have the level `info`
  --style RULECODE         Make the rule `RULECODE` have the level `style`
  --ignore RULECODE        A rule to ignore. If present, the ignore list in the
                           config file is ignored
  --trusted-registry REGISTRY (e.g. docker.io)
                           A docker registry to allow to appear in FROM
                           instructions
  --require-label LABELSCHEMA (e.g. maintainer:text)
                           The option --require-label=label:format makes
                           Hadolint check that the label `label` conforms to
                           format requirement `format`
  --strict-labels          Do not permit labels other than specified in
                           `label-schema`
  -t,--failure-threshold THRESHOLD
                           Exit with failure code only when rules with a
                           severity above THRESHOLD are violated. Accepted
                           values: [error | warning | info | style | ignore |
                           none] (default: info)

Configure

Configuration files can be used globally or per project. By default,hadolint looks for a configuration file named .hadolint.yaml or.hadolint.yml in the current directory.

hadolint full yaml config file schema

failure-threshold: string               # name of threshold level (error | warning | info | style | ignore | none)                
format: string                          # Output format (tty | json | checkstyle | codeclimate | gitlab_codeclimate | codacy)
ignored: [string]                       # list of rules
label-schema:                           # See Linting Labels below for specific label-schema details
  author: string                        # Your name
  contact: string                       # email address
  created: timestamp                    # rfc3339 datetime
  version: string                       # semver
  documentation: string                 # url
  git-revision: string                  # hash
  license: string                       # spdx
no-color: boolean                       # true | false
no-fail: boolean                        # true | false
override:
  error: [string]                       # list of rules
  warning: [string]                     # list of rules
  info: [string]                        # list of rules
  style: [string]                       # list of rules
strict-labels: boolean                  # true | false
trustedRegistries: string | [string]    # registry or list of registries

hadolint supports specifying the ignored rules using a configurationfile. The configuration file should be in yaml format. This is onevalid configuration file as an example:

ignored:
  - DL3000
  - SC1010

Additionally, hadolint can warn you when images from untrustedrepositories are being used in Dockerfiles, you can append thetrustedRegistries keys to the configuration file, as shown below:

ignored:
  - DL3000
  - SC1010

trustedRegistries:
  - docker.io
  - my-company.com:5000

If you want to override the severity of specific rules, you can do that too:

override:
  error:
    - DL3001
    - DL3002
  warning:
    - DL3042
    - DL3033
  info:
    - DL3032
  style:
    - DL3015

failure-threshold Exit with failure code only when rules with aseverity above THRESHOLD are violated (Available in v2.6.0+)

failure-threshold: info
warning:
    - DL3042
    - DL3033
  info:
    - DL3032

The global configuration file should be placed in the folderspecified by XDG_CONFIG_HOME,with the name hadolint.yaml or hadolint.yml. In summary, thefollowing locations are valid for the configuration file, in orderor preference:

  • $PWD/.hadolint.yaml
  • $XDG_CONFIG_HOME/hadolint.yaml
  • ~/.config/hadolint.yaml

In windows, the %LOCALAPPDATA% environment variable is used instead of XDG_CONFIG_HOME

Additionally, you can pass a custom configuration file in the command line withthe --config option

hadolint --config /path/to/config.yaml Dockerfile

To pass a custom configuration file (using relative or absolute path) toa container, use the following command:

docker run --rm -i -v /your/path/to/hadolint.yaml:/.config/hadolint.yaml hadolint/hadolint < Dockerfile
# OR
docker run --rm -i -v /your/path/to/hadolint.yaml:/.config/hadolint.yaml ghcr.io/hadolint/hadolint < Dockerfile

Inline ignores

It is also possible to ignore rules by adding a special comment directlyabove the Dockerfile statement for which you want to make an exception for.Such comments look like# hadolint ignore=DL3001,SC1081. For example:

# hadolint ignore=DL3006
FROM ubuntu

# hadolint ignore=DL3003,SC1035
RUN cd /tmp && echo "hello!"

The comment "inline ignores" applies only to the statement following it.

Linting Labels

Hadolint is able to check if specific labels are present and conformto a predefined label schema.First, a label schema must be defined either via the command line:

hadolint --require-label author:text --require-label version:semver Dockerfile

or via the config file:

label-schema:
  author: text
  contact: email
  created: rfc3339
  version: semver
  documentation: url
  git-revision: hash
  license: spdx

The value of a label can be either of text, url, semver, hash orrfc3339:

Schema Description
text Anything
rfc3339 A time, formatted according to RFC 3339
semver A semantic version
url A URI as described in RFC 3986
hash Either a short or a long Git hash
spdx An SPDX license identifier
email An email address conforming to RFC 5322

By default, Hadolint ignores any label that is not specified in the label schema. Towarn against such additional labels, turn on strict labels, using the command line:

hadolint --strict-labels --require-label version:semver Dockerfile

or the config file:

strict-labels: true

When strict labels is enabled, but no label schema is specified, hadolintwill warn if any label is present.

Note on dealing with variables in labels

It is a common pattern to fill the value of a label not statically, but ratherdynamically at build time by using a variable:

FROM debian:buster
ARG VERSION="du-jour"
LABEL version="${VERSION}"

To allow this, the label schema must specify text as value for that label:

label-schema:
  version: text

Integrations

To get most of hadolint, it is useful to integrate it as a check in your CIor into your editor, or as a pre-commit hook, to lint your Dockerfile as youwrite it. See our Integration docs.

Rules

An incomplete list of implemented rules. Click on the error code to get moredetailed information.

  • Rules with the prefix DL are from hadolint. Have a look atRules.hs to find the implementation of the rules.

  • Rules with the SC prefix are from ShellCheck (only the mostcommon rules are listed, there are dozens more).

Please create an issue if you have an idea for a good rule.

Rule Default Severity Description
DL3000 Error Use absolute WORKDIR.
DL3001 Info 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 Warning Last user should not be root.
DL3003 Warning Use WORKDIR to switch to a directory.
DL3004 Error Do not use sudo as it leads to unpredictable behavior. Use a tool like gosu to enforce root.
DL3005 Error Do not use apt-get dist-upgrade.
DL3006 Warning Always tag the version of an image explicitly.
DL3007 Warning Using latest is prone to errors if the image will ever update. Pin the version explicitly to a release tag.
DL3008 Warning Pin versions in apt-get install.
DL3009 Info Delete the apt-get lists after installing something.
DL3010 Info Use ADD for extracting archives into an image.
DL3011 Error Valid UNIX ports range from 0 to 65535.
DL3012 Error Multiple HEALTHCHECK instructions.
DL3013 Warning Pin versions in pip.
DL3014 Warning Use the -y switch.
DL3015 Info Avoid additional packages by specifying --no-install-recommends.
DL3016 Warning Pin versions in npm.
DL3018 Warning Pin versions in apk add. Instead of apk add <package> use apk add <package>=<version>.
DL3019 Info Use the --no-cache switch to avoid the need to use --update and remove /var/cache/apk/* when done installing packages.
DL3020 Error Use COPY instead of ADD for files and folders.
DL3021 Error COPY with more than 2 arguments requires the last argument to end with /
DL3022 Warning COPY --from should reference a previously defined FROM alias
DL3023 Error COPY --from cannot reference its own FROM alias
DL3024 Error FROM aliases (stage names) must be unique
DL3025 Warning Use arguments JSON notation for CMD and ENTRYPOINT arguments
DL3026 Error Use only an allowed registry in the FROM image
DL3027 Warning Do not use apt as it is meant to be a end-user tool, use apt-get or apt-cache instead
DL3028 Warning Pin versions in gem install. Instead of gem install <gem> use gem install <gem>:<version>
DL3029 Warning Do not use --platform flag with FROM.
DL3030 Warning Use the -y switch to avoid manual input yum install -y <package>
DL3032 Warning yum clean all missing after yum command.
DL3033 Warning Specify version with yum install -y <package>-<version>
DL3034 Warning Non-interactive switch missing from zypper command: zypper install -y
DL3035 Warning Do not use zypper dist-upgrade.
DL3036 Warning zypper clean missing after zypper use.
DL3037 Warning Specify version with zypper install -y <package>[=]<version>.
DL3038 Warning Use the -y switch to avoid manual input dnf install -y <package>
DL3040 Warning dnf clean all missing after dnf command.
DL3041 Warning Specify version with dnf install -y <package>-<version>
DL3042 Warning Avoid cache directory with pip install --no-cache-dir <package>.
DL3043 Error ONBUILD, FROM or MAINTAINER triggered from within ONBUILD instruction.
DL3044 Error Do not refer to an environment variable within the same ENV statement where it is defined.
DL3045 Warning COPY to a relative destination without WORKDIR set.
DL3046 Warning useradd without flag -l and high UID will result in excessively large Image.
DL3047 Info wget without flag --progress will result in excessively bloated build logs when downloading larger files.
DL3048 Style Invalid Label Key
DL3049 Info Label <label> is missing.
DL3050 Info Superfluous label(s) present.
DL3051 Warning Label <label> is empty.
DL3052 Warning Label <label> is not a valid URL.
DL3053 Warning Label <label> is not a valid time format - must be conform to RFC3339.
DL3054 Warning Label <label> is not a valid SPDX license identifier.
DL3055 Warning Label <label> is not a valid git hash.
DL3056 Warning Label <label> does not conform to semantic versioning.
DL3057 IgnoreC HEALTHCHECK instruction missing.
DL3058 Warning Label <label> is not a valid email format - must be conform to RFC5322.
DL3059 Info Multiple consecutive RUN instructions. Consider consolidation.
DL3060 Info yarn cache clean missing after yarn install was run.
DL4000 Error MAINTAINER is deprecated.
DL4001 Warning Either use Wget or Curl but not both.
DL4003 Warning Multiple CMD instructions found.
DL4004 Error Multiple ENTRYPOINT instructions found.
DL4005 Warning Use SHELL to change the default shell.
DL4006 Warning Set the SHELL option -o pipefail before RUN with a pipe in it
SC1000 $ is not used specially and should therefore be escaped.
SC1001 This \c will be a regular 'c' in this context.
SC1007 Remove space after = if trying to assign a value (or for empty string, use var='' ...).
SC1010 Use semicolon or linefeed before done (or quote to make it literal).
SC1018 This is a unicode non-breaking space. Delete it and retype as space.
SC1035 You need a space here
SC1045 It's not foo &; bar, just foo & bar.
SC1065 Trying to declare parameters? Don't. Use () and refer to params as $1, $2 etc.
SC1066 Don't use $ on the left side of assignments.
SC1068 Don't put spaces around the = in assignments.
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 if, not If.
SC1083 This {/} is literal. Check expression (missing ;/\n?) or quote it.
SC1086 Don't use $ on the iterator name in for loops.
SC1087 Braces are required when expanding arrays, as in ${array[idx]}.
SC1095 You need a space or linefeed between the function name and body.
SC1097 Unexpected ==. For assignment, use =. For comparison, use [ .. ] or [[ .. ]].
SC1098 Quote/escape special characters when using eval, e.g. eval "a=(b)".
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'?
SC2028 echo won't expand escape sequences. Consider printf.
SC2035 Use ./*glob* or -- *glob* so names with dashes won't become options.
SC2039 In POSIX sh, something is undefined.
SC2046 Quote this to prevent word splitting
SC2086 Double quote to prevent globbing and word splitting.
SC2140 Word is in the form "A"B"C" (B indicated). Did you mean "ABC" or "A\"B\"C"?
SC2154 var is referenced but not assigned.
SC2155 Declare and assign separately to avoid masking return values.
SC2164 Use cd ... || exit in case cd fails.

Develop

If you are an experienced Haskeller, we would be very grateful if you wouldtear our code apart in a review.

Setup

  1. Clone repository

    git clone --recursive git@github.com:hadolint/hadolint.git
  2. Install the dependencies

    stack install

REPL

The easiest way to try out the parser is using the REPL.

# start the repl
stack repl
# overload strings to be able to use Text
:set -XOverloadedStrings
# import parser library
import Language.Docker
# parse instruction and look at AST representation
parseText "FROM debian:jessie"

Tests

Run unit tests:

stack test

Run integration tests:

./integration_test.sh

AST

Dockerfile syntax is fully described in the Dockerfile reference.Just take a look at Syntax.hs in the language-docker project to seethe AST definition.

Alternatives

  • Hadolint 是Haskell 实现的 Dockerfile linter,现依据Docker 官网推荐的 Dockerfile 最佳实践。 安装: alias hadolint='docker run --rm -i hub.baidubce.com/duanshuaixing/hadolint/hadolint:latest-alpine < ' [root@allinone ~]# h