
一个更聪明的Dockerfile林格,可帮助您构建最佳的练习Docker图像。 Linter将Dockerfile解析为AST,并在AST之上执行规则。它站在ShellCheck的肩膀上,可以在RUN说明中提起BASH代码。
在hadolint.github.io/hadolint上检查在线版本
您可以在本地运行hadolint来凸显您的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参加了救援,这为大多数平台上的hadolint提供了一种简单的方法。只需将您的Dockerfile带到docker run :
docker run --rm -i hadolint/hadolint < Dockerfile
# OR
docker run --rm -i ghcr.io/hadolint/hadolint < Dockerfile或使用Podman:
podman run --rm -i docker.io/hadolint/hadolint < Dockerfile
# OR
podman run --rm -i ghcr.io/hadolint/hadolint < Dockerfile或使用Windows PowerShell:
cat .Dockerfile | docker run -- rm - i hadolint / hadolint您可以从最新版本页面下载用于OSX,Windows和Linux的预构建二进制文件。但是,如果这对您不起作用,请回到容器(Docker), brew或源安装。
在OSX上,您可以使用Brew安装hadolint 。
brew install hadolint在Windows上,您可以使用SCOOP安装hadolint 。
scoop install hadolint在安装了nix的发行版中,您可以使用hadolint软件包运行临时壳或永久安装hadolint到您的环境中。
如前所述, hadolint可作为容器图像提供:
docker pull hadolint/hadolint
# OR
docker pull ghcr.io/hadolint/hadolint如果您需要带有外壳访问的容器,请使用Debian或Alpine变体:
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您也可以在本地建造hadolint 。您需要Haskell和Cabal Build工具来构建二进制文件。
git clone https://github.com/hadolint/hadolint
&& cd hadolint
&& cabal configure
&& cabal build
&& cabal install如果要在容器中使用Hadolint的VS代码Hadolint扩展名,则可以使用以下包装脚本:
#! /bin/bash
dockerfile= " $1 "
shift
docker run --rm -i hadolint/hadolint hadolint " $@ " - < " $dockerfile " hadolint --help hadolint - Dockerfile Linter written in Haskell
Usage: hadolint [-v|--version] [-c|--config FILENAME] [DOCKERFILE...]
[--file-path-in-report FILEPATHINREPORT] [--no-fail]
[--no-color] [-V|--verbose] [-f|--format ARG] [--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] [--disable-ignore-pragma]
[-t|--failure-threshold THRESHOLD]
Lint Dockerfile for errors and best practices
Available options:
-h,--help Show this help text
-v,--version Show version
-c,--config FILENAME Path to the configuration file
--file-path-in-report FILEPATHINREPORT
The file path referenced in the generated report.
This only applies for the 'checkstyle' format and is
useful when running Hadolint with Docker to set the
correct file path.
--no-fail Don't exit with a failure status code when any rule
is violated
--no-color Don't colorize output
-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 | gnu |
codacy | sonarqube | sarif] (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`
--disable-ignore-pragma Disable inline ignore pragmas `# hadolint
ignore=DLxxxx`
-t,--failure-threshold THRESHOLD
Exit with failure code only when rules with a
severity equal to or above THRESHOLD are violated.
Accepted values: [error | warning | info | style |
ignore | none] (default: info)
配置文件可以在全球或每个项目上使用。 Hadolint在以下位置查找配置文件或以此顺序为特定平台的同等文件,并专门使用第一个:
$PWD/.hadolint.yaml$XDG_CONFIG_HOME/hadolint.yaml$HOME/.config/hadolint.yaml$HOME/.hadolint/hadolint.yaml or $HOME/hadolint/config.yaml$HOME/.hadolint.yaml在Windows中,使用%LOCALAPPDATA%环境变量而不是XDG_CONFIG_HOME 。配置文件可以具有yaml或yml扩展名。
hadolint完整yaml配置文件架构
failure-threshold : string # name of threshold level (error | warning | info | style | ignore | none)
format : string # Output format (tty | json | checkstyle | codeclimate | gitlab_codeclimate | gnu | 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
disable-ignore-pragma : boolean # true | false
trustedRegistries : string | [string] # registry or list of registries hadolint支持使用配置文件指定忽略规则。配置文件应为yaml格式。这是一个有效的配置文件,例如:
ignored :
- DL3000
- SC1010此外, hadolint可以在Dockerfiles中使用不信任存储库的图像时警告您,您可以将trustedRegistries键附加到配置文件中,如下所示:
ignored :
- DL3000
- SC1010
trustedRegistries :
- docker.io
- my-company.com:5000
- " *.gcr.io "如果要覆盖特定规则的严重性,也可以做到这一点:
override :
error :
- DL3001
- DL3002
warning :
- DL3042
- DL3033
info :
- DL3032
style :
- DL3015仅当违反严重程度高于阈值的规则时failure-threshold出口就会出现故障代码(可在v2.6.0+中使用)
failure-threshold : info
override :
warning :
- DL3042
- DL3033
info :
- DL3032此外,您可以使用--config选项将自定义配置文件传递在命令行中的自定义配置文件
hadolint --config /path/to/config.yaml Dockerfile要将自定义配置文件(使用相对或绝对路径)传递到容器中,请使用以下命令:
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除了配置文件外,还可以使用环境变量配置Hadolint。
NO_COLOR=1 # Set or unset. See https://no-color.org
HADOLINT_NOFAIL=1 # Truthy value e.g. 1, true or yes
HADOLINT_VERBOSE=1 # Truthy value e.g. 1, true or yes
HADOLINT_FORMAT=json # Output format (tty | json | checkstyle | codeclimate | gitlab_codeclimate | gnu | codacy | sarif )
HADOLINT_FAILURE_THRESHOLD=info # threshold level (error | warning | info | style | ignore | none)
HADOLINT_OVERRIDE_ERROR=DL3010,DL3020 # comma separated list of rule codes
HADOLINT_OVERRIDE_WARNING=DL3010,DL3020 # comma separated list of rule codes
HADOLINT_OVERRIDE_INFO=DL3010,DL3020 # comma separated list of rule codes
HADOLINT_OVERRIDE_STYLE=DL3010,DL3020 # comma separated list of rule codes
HADOLINT_IGNORE=DL3010,DL3020 # comma separated list of rule codes
HADOLINT_STRICT_LABELS=1 # Truthy value e.g. 1, true or yes
HADOLINT_DISABLE_IGNORE_PRAGMA=1 # Truthy value e.g. 1, true or yes
HADOLINT_TRUSTED_REGISTRIES=docker.io # comma separated list of registry urls
HADOLINT_REQUIRE_LABELS=maintainer:text # comma separated list of label schema items 当将基本图像与非posix shell作为默认值(例如基于Windows的图像)时,特殊的Pragma hadolint shell可以指定基本图像使用的外壳,因此Hadolint可以自动忽略所有特定于外壳的规则。
FROM mcr.microsoft.com/windows/servercore:ltsc2022
# hadolint shell=powershell
RUN Get-Process notepad | Stop-Process也可以通过直接在Dockerfile语句上方添加特殊评论来忽略规则,您要为其进行例外。这样的评论看起来像# hadolint ignore=DL3001,SC1081 。例如:
# hadolint ignore=DL3006
FROM ubuntu
# hadolint ignore=DL3003,SC1035
RUN cd /tmp && echo "hello!"评论“内联”仅适用于之后的语句。
也可以使用全局忽略Pragma以每文件的基础忽略规则。它的工作方式与内联忽略一样,除了它适用于整个文件,而不仅仅是下一行。
# hadolint global ignore=DL3003,DL3006,SC1035
FROM ubuntu
RUN cd /tmp && echo "foo" Hadolint能够检查是否存在特定标签并符合预定义的标签模式。首先,必须通过命令行来定义标签架构:
hadolint --require-label author:text --require-label version:semver Dockerfile或通过配置文件:
label-schema :
author : text
contact : email
created : rfc3339
version : semver
documentation : url
git-revision : hash
license : spdx标签的值可以是text , url , semver , hash或rfc3339 :
| 模式 | 描述 |
|---|---|
| 文本 | 任何事物 |
| RFC3339 | 根据RFC 3339格式化的时间 |
| SEMVER | 语义版本 |
| URL | RFC 3986中所述的URI |
| 哈希 | 短或长git |
| spdx | SPDX许可证标识符 |
| 电子邮件 | 符合RFC 5322的电子邮件地址 |
默认情况下,Hadolint忽略了标签架构中未指定的任何标签。要警告此类其他标签,请使用命令行打开严格的标签:
hadolint --strict-labels --require-label version:semver Dockerfile或配置文件:
strict-labels : true当启用严格的标签,但未指定标签模式时, hadolint会警告如果有任何标签。
这是一个常见的模式,可以通过使用变量在构建时间动态地填充标签的值:
FROM debian:buster
ARG VERSION= "du-jour"
LABEL version= "${VERSION}"为此,标签架构必须将text指定为该标签的值:
label-schema :
version : text 为了获得大多数hadolint ,将其作为检查中的检查或编辑器或作为预先承诺的挂钩将其集成在一起是有用的,以便在编写码头时提起您的Dockerfile 。请参阅我们的集成文档。
实施规则的不完整列表。单击错误代码以获取更多详细信息。
前缀DL的规则来自hadolint 。请查看Rules.hs查找规则的实施。
SC前缀的规则来自ShellCheck (仅列出了最常见的规则,更多的规则)。
如果您有一个好的规则,请创建一个问题。
| 规则 | 默认严重性 | 描述 |
|---|---|---|
| DL1001 | 忽略 | 请避免使用内联忽略Pragmas # hadolint ignore=DLxxxx 。 |
| DL3000 | 错误 | 使用绝对工作迪尔。 |
| DL3001 | 信息 | 对于某些bash命令,在SSH,VIM,关闭,服务,PS,Free,Top,Top,Kill,Mount,IfConfig等码头容器中运行它们是没有意义的。 |
| DL3002 | 警告 | 最后一个用户不应是根。 |
| DL3003 | 警告 | 使用WorkDir切换到目录。 |
| DL3004 | 错误 | 不要使用sudo会导致不可预测的行为。使用像GOSU这样的工具来强制根。 |
| DL3006 | 警告 | 始终明确标记图像的版本。 |
| DL3007 | 警告 | 如果图像将不断更新,则使用最新方法容易出现错误。将版本明确地固定在发布标签上。 |
| DL3008 | 警告 | apt-get install中的引脚版本。 |
| DL3009 | 信息 | 安装某些内容后,删除APT-GET列表。 |
| DL3010 | 信息 | 使用添加以将档案提取到图像中。 |
| DL3011 | 错误 | 有效的UNIX端口范围从0到65535。 |
| DL3012 | 错误 | 多个HEALTHCHECK说明。 |
| DL3013 | 警告 | PIP中的引脚版本。 |
| DL3014 | 警告 | 使用-y开关。 |
| DL3015 | 信息 | 避免通过指定--no-install-recommends来避免其他软件包。 |
| DL3016 | 警告 | npm中的引脚版本。 |
| DL3018 | 警告 | apk add中的PIN版本。而不是apk add <package>使用apk add <package>=<version> 。 |
| DL3019 | 信息 | 使用--no-cache开关来避免使用时需要--update上升/var/cache/apk/*安装软件包时。 |
| DL3020 | 错误 | 使用COPY而不是ADD文件和文件夹。 |
| DL3021 | 错误 | 具有两个以上参数的COPY要求最后一个参数以/结尾 |
| DL3022 | 警告 | COPY --from应引用先前定义的FROM |
| DL3023 | 错误 | COPY --from不能从别名FROM引用自己的 |
| DL3024 | 错误 | FROM别名(舞台名称)必须是唯一的 |
| DL3025 | 警告 | 使用参数JSON符号用于CMD和入口处参数 |
| DL3026 | 错误 | 仅在FROM image中使用允许的注册表 |
| DL3027 | 警告 | 请勿使用apt ,因为它本来是最终用户工具,而是使用apt-get或apt-cache |
| DL3028 | 警告 | GEM安装中的引脚版本。而不是gem install <gem>使用gem install <gem>:<version> |
| DL3029 | 警告 | 请勿使用-platform标志。 |
| DL3030 | 警告 | 使用-y开关避免手动输入yum install -y <package> |
| DL3032 | 警告 | yum clean all丢失的命令。 |
| DL3033 | 警告 | 用yum install -y <package>-<version>指定版本 |
| DL3034 | 警告 | zypper命令中缺少非相互作用开关: zypper install -y |
| DL3035 | 警告 | 请勿使用zypper dist-upgrade 。 |
| DL3036 | 警告 | zypper clean使用Zypper后丢失。 |
| DL3037 | 警告 | 用zypper install -y <package>[=]<version>指定版本。 |
| DL3038 | 警告 | 使用-y开关避免手动输入dnf install -y <package> |
| DL3040 | 警告 | dnf clean all丢失。 |
| DL3041 | 警告 | 用dnf install -y <package>-<version>指定版本 |
| DL3042 | 警告 | 避免使用pip install --no-cache-dir <package> 。 |
| DL3043 | 错误 | ONBUILD ,从内部ONBUILD指令内部FROM或MAINTAINER 。 |
| DL3044 | 错误 | 请勿在定义其定义的同一ENV语句中参考环境变量。 |
| DL3045 | 警告 | COPY无WORKDIR集的相对目的地。 |
| DL3046 | 警告 | 没有标志-l和高UID的useradd会导致过多的图像。 |
| DL3047 | 信息 | 没有标志的wget --progress下载较大的文件时将导致过度膨胀的构建日志。 |
| DL3048 | 风格 | 无效标签键 |
| DL3049 | 信息 | 标签<label>缺少。 |
| DL3050 | 信息 | 存在多余的标签。 |
| DL3051 | 警告 | 标签<label>是空的。 |
| DL3052 | 警告 | Label <label>不是有效的URL。 |
| DL3053 | 警告 | 标签<label>不是有效的时间格式 - 必须符合RFC3339。 |
| DL3054 | 警告 | Label <label>不是有效的SPDX许可证标识符。 |
| DL3055 | 警告 | 标签<label>不是有效的git哈希。 |
| DL3056 | 警告 | Label <label>不符合语义版本。 |
| DL3057 | 忽略 | HEALTHCHECK教学缺失。 |
| DL3058 | 警告 | 标签<label>不是有效的电子邮件格式 - 必须符合RFC5322。 |
| DL3059 | 信息 | 多个连续RUN说明。考虑合并。 |
| DL3060 | 信息 | 运行yarn install后, yarn cache clean缺失。 |
| DL3061 | 错误 | 无效的说明令。 Dockerfile必须ARG FROM评论开始。 |
| DL4000 | 错误 | MAINTAINER被弃用。 |
| DL4001 | 警告 | 使用WGET或Curl,但不能同时使用。 |
| DL4003 | 警告 | 找到了多个CMD指令。 |
| DL4004 | 错误 | 找到多个ENTRYPOINT指令。 |
| DL4005 | 警告 | 使用SHELL更改默认外壳。 |
| DL4006 | 警告 | 在用管道RUN之前,请设置SHELL Option -O PipeFail |
| SC1000 | $不是专门使用的,因此应逃脱。 | |
| SC1001 | 在这种情况下,此c将是常规的'c' 。 | |
| SC1007 | 在=试图分配值(或为空字符串,使用var='' ... )之后删除空间。 | |
| SC1010 | 在done之前,请使用semicolon或lineFeed(或引用将其进行字面意思)。 | |
| SC1018 | 这是一个非破坏空间。将其删除并重新输入空间。 | |
| SC1035 | 您需要在这里一个空间 | |
| SC1045 | 这不是foo &; bar ,只是foo & bar 。 | |
| SC1065 | 试图声明参数?不。使用() ,并将参数称为$1 , $2等。 | |
| SC1066 | 不要在作业的左侧使用$。 | |
| SC1068 | 不要在分配中放置=周围的空间。 | |
| SC1077 | 为了扩展命令,tick应向左倾斜(`vs’)。 | |
| SC1078 | 您是否忘记关闭了这个双重引用的字符串? | |
| SC1079 | 这实际上是最终报价,但由于下一个字符,它看起来令人怀疑。 | |
| SC1081 | 脚本是案例敏感的。 if使用, If使用。 | |
| SC1083 | 这个{/}是字面的。检查表达式(缺少;/n ?)或引用它。 | |
| SC1086 | 不要在迭代器名称上使用$进行循环。 | |
| SC1087 | 扩展数组时需要牙套,如${array[idx]}中。 | |
| SC1095 | 您需要功能名称和车身之间的空间或线馈。 | |
| SC1097 | 意外== 。要分配,请使用= 。为了进行比较,请使用[ .. ]或[[ .. ]] 。 | |
| SC1098 | 引用/逃脱特殊字符时,例如,例如eval eval "a=(b)" 。 | |
| SC1099 | 您需要#之前的空间。 | |
| SC2002 | 无用的猫。考虑cmd < file | ..或cmd file | ..反而。 | |
| SC2015 | 请注意, A && B || C不是else。 C可能在A为真时运行。 | |
| SC2026 | 这个词不在报价之外。您是否打算“嵌套”““单样”'“而不是”? | |
| SC2028 | echo不会扩展逃生序列。考虑printf 。 | |
| SC2035 | 使用./*glob*或-- *glob* ,因此带有破折号的名称不会成为选项。 | |
| SC2039 | 在Posix SH中,有些不确定。 | |
| SC2046 | 引用这一点是为了防止单词分裂 | |
| SC2086 | 双引号以防止球形和单词分裂。 | |
| SC2140 | 单词以"A"B"C" (b表示)形式。您的意思是"ABC"或"A"B"C" ? | |
| SC2154 | var被引用但未分配。 | |
| SC2155 | 单独声明并分配以避免掩盖返回值。 | |
| SC2164 | 使用cd ... || exit如果cd失败, cd ... || exit 。 |
如果您是一个经验丰富的Haskeller,那么如果您在评论中将我们的代码分开,我们将非常感谢。
要编译,您将需要最近的Haskell环境和cabal-install 。
克隆存储库
git clone --recursive [email protected]:hadolint/hadolint.git安装依赖项和编译源
cabal configure
cabal build(可选)在系统上安装Hadolint
cabal install尝试解析器的最简单方法是使用替补。
# start the repl
cabal 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 "通过单位测试进行编译并运行它们:
cabal configure --enable-tests
cabal build --enable-tests
cabal test运行集成测试:
./integration_test.sh Dockerfile语法在Dockerfile参考中充分描述。只需查看language-docker项目中的语法即可查看AST定义。
Hadolint使用许多图书馆来完成肮脏的工作。特别是,语言骗子用于解析Dockerfiles并产生AST,然后可以分析该AST。要针对此类库的自定义版本构建Hadolint,请执行以下操作。此示例使用语言骗子,但它也可以与任何其他库一起使用。
/home/user/repos )克隆Hadolint和语言docker git存储库中 cd /home/user/repos
git clone https://github.com/hadolint/hadolint.git
git clone https://github.com/hadolint/language-docker.git对语言骗子进行修改
在Hadolint仓库中,编辑cabal.project文件,以便packages属性也指向另一个存储库
[...]
packages :
.
../language-docker
[...] cd /home/user/repos/hadolint
cabal configure --enable-tests
cabal build --enable-tests
cabal test ReplicatedHQ/DockerFileLint,超级链接使用的另一个Linter
RedCoolbeans/dockerlint
projectatomic/dockerfile_lint