DL4006 警告:在带有管道的 RUN 之前设置 SHELL 选项 -o pipelinefail

Hon*_*iao 12 lint dockerfile hadolint

我有一个 Dockerfile

FROM strimzi/kafka:0.20.1-kafka-2.6.0

USER root:root
RUN mkdir -p /opt/kafka/plugins/debezium
# Download, unpack, and place the debezium-connector-postgres folder into the /opt/kafka/plugins/debezium directory
RUN curl -s https://repo1.maven.org/maven2/io/debezium/debezium-connector-postgres/1.7.0.Final/debezium-connector-postgres-1.7.0.Final-plugin.tar.gz | tar xvz --transform 's/debezium-connector-postgres/debezium/' --directory /opt/kafka/plugins/
USER 1001
Run Code Online (Sandbox Code Playgroud)

当我对它使用hadolint时

hadolint Dockerfile
Run Code Online (Sandbox Code Playgroud)

我收到警告

Dockerfile:6 DL4006 警告:在使用管道运行之前设置 SHELL 选项 -o pipelinefail。如果您在 alpine 映像中使用 /bin/sh 或者您的 shell 符号链接到 busybox,则考虑将您的 SHELL 显式设置为 /bin/ash,或禁用此检查

|我知道我的生产线上有一个以 开头的管道RUN

但是,我仍然不知道如何根据此警告进行修复。

Hon*_*iao 18

哦,刚刚在 wiki 页面找到了解决方案https://github.com/hadolint/hadolint/wiki/DL4006

这是我的固定版本:

FROM strimzi/kafka:0.20.1-kafka-2.6.0

USER root:root
RUN mkdir -p /opt/kafka/plugins/debezium
# Download, unpack, and place the debezium-connector-postgres folder into the /opt/kafka/plugins/debezium directory
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
RUN curl -s https://repo1.maven.org/maven2/io/debezium/debezium-connector-postgres/1.7.0.Final/debezium-connector-postgres-1.7.0.Final-plugin.tar.gz | tar xvz --transform 's/debezium-connector-postgres/debezium/' --directory /opt/kafka/plugins/
USER 1001
Run Code Online (Sandbox Code Playgroud)

添加的原因SHELL ["/bin/bash", "-o", "pipefail", "-c"]位于https://github.com/docker/docker.github.io/blob/master/develop/develop-images/dockerfile_best-practices.md#using-pipes

以下是副本:


某些RUN命令依赖于使用管道字符 ( ) 将一个命令的输出通过管道传输到另一个命令的能力|,如下例所示:

RUN wget -O - https://some.site | wc -l > /number
Run Code Online (Sandbox Code Playgroud)

Docker 使用解释器执行这些命令/bin/sh -c,解释器仅评估管道中最后一个操作的退出代码以确定是否成功。在上面的示例中,只要wc -l命令成功,即使命令wget失败,此构建步骤也会成功并生成新映像。

如果您希望命令由于管道中任何阶段的错误而失败,请预先设置set -o pipefail &&以确保意外错误防止构建意外成功。例如:

RUN set -o pipefail && wget -O - https://some.site | wc -l > /number
Run Code Online (Sandbox Code Playgroud)

并非所有 shell 都支持该-o pipefail选项。

dash对于基于 Debian 的映像上的 shell等情况,请考虑使用exec形式RUN来显式选择支持该pipefail选项的 shell。例如:

RUN ["/bin/bash", "-c", "set -o pipefail && wget -O - https://some.site | wc -l > /number"]
Run Code Online (Sandbox Code Playgroud)