首页 > 解决方案 > DL4006 警告:在 RUN 之前设置 SHELL 选项 -o pipefail,其中包含管道

问题描述

我有一个 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

当我在它上面使用hadolint

hadolint Dockerfile

我收到警告

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

我知道我有一个以 .|开头的管道RUN

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

标签: dockerfilelinthadolint

解决方案


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

这是我的固定版本:

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

添加的原因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

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

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

RUN set -o pipefail && wget -O - https://some.site | wc -l > /number

并非所有 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"]

推荐阅读