Docker中的条件块

9

我已经使用Docker一段时间了。 我遇到了一个情况,需要根据某些条件执行Dockerfile中的指令。 例如,这里是Dockerfile的片段:

FROM centos:centos7
MAINTAINER Akshay <akshay@dm.com>

# Update and install required binaries
RUN yum update -y \
    && yum install -y which wget openssh-server sudo java-1.8.0-openjdk \
    && yum clean all

#install Maven
RUN curl -Lf http://archive.apache.org/dist/maven/maven-3/3.3.9/binaries/apache-maven-3.3.9-bin.tar.gz -o /tmp/apache-maven-3.3.9.tar.gz
RUN tar -xzf /tmp/apache-maven-3.3.9.tar.gz -C /opt \
        && rm /tmp/apache-maven-3.3.9.tar.gz

ENV M2_HOME "/opt/apache-maven-3.3.9"
ENV PATH ${PATH}:${M2_HOME}/bin:

# Install Ant
ENV ANT_VERSION 1.9.4
RUN cd && \
    wget -q http://archive.apache.org/dist/ant/binaries/apache-ant-${ANT_VERSION}-bin.tar.gz && \
    tar -xzf apache-ant-${ANT_VERSION}-bin.tar.gz && \
    mv apache-ant-${ANT_VERSION} /opt/ant && \
    rm apache-ant-${ANT_VERSION}-bin.tar.gz
ENV ANT_HOME /opt/ant
ENV PATH ${PATH}:/opt/ant/bin
......

因此,您可以在我的Docker文件中看到我有maven和ant的安装说明。但是现在,我必须根据条件安装其中一个。我知道我可以在Dockerfile中使用ARG指令在构建时获取参数,但问题在于我找不到任何关于如何将它们包含在if/else块中的文档。
我也阅读了其他一些stackoverflow帖子,但在这些帖子中,他们要求在指令内部使用条件语句,例如RUN if $BUILDVAR -eq "SO"; then export SOMEVAR=hello; else export SOMEVAR=world; fi链接或编写一个单独的脚本文件,例如这个。但正如您所见,我的情况是不同的。由于还有许多其他指令取决于该参数,因此我无法使用它们。我必须做这样的事情
ARG BUILD_TOOL  
if [ "${BUILD_TOOL}" = "MAVEN" ]; then
--install maven
elif [ "${BUILD_TOOL}" = "ANT" ]; then
--install ant
fi
.... other instructions ....
if [ "${BUILD_TOOL}" = "MAVEN" ]; then
    --some other dependent commands
elif [ "${BUILD_TOOL}" = "ANT" ]; then
    --some other dependent commands
fi

请参见 https://dev59.com/HFcP5IYBdhLWcg3w5eDQ#60820156,了解不需要任何 bash 的条件 Docker 文件。 - User12547645
1个回答

9

如果您不想使用所有这些RUN if语句,可以创建一个bash脚本来进行设置过程,并从Dockerfile中调用它。例如:

FROM centos:centos7
MAINTAINER Someone <someone@email.com>

ARG BUILD_TOOL

COPY setup.sh /setup.sh

RUN ./setup.sh

RUN rm /setup.sh

还有 setup.sh 文件(不要忘记将其设置为可执行文件):

if [ "${BUILD_TOOL}" = "MAVEN" ]; then
    echo "Step 1 of MAVEN setup";
    echo "(...)";
    echo "Done MAVEN setup";
elif [ "${BUILD_TOOL}" = "ANT" ]; then
    echo "Step 1 of ANT setup";
    echo "(...)";
    echo "Done ANT setup";
fi

您可以使用docker build --build-arg BUILD_TOOL=MAVEN .(或者ANT)来构建它。
请注意,我在这里使用了一个shell脚本,但是如果您有其他解释器可用(例如:python或ruby),您也可以使用它们编写设置脚本。

谢谢您的评论。是的,我也考虑过这种解决方案。但问题在于我应该有多个脚本,因为检查该条件应导致执行不同的Docker指令。所以它会像这样,在执行setup.sh之后,再根据该条件执行configure.sh和另一个execute.sh等等。我觉得这样做会非常繁琐。因此,如果有其他方法可以完成此操作,那就想一下。如果我错了,请纠正我。 - DMA
你能给一个具体的例子吗?因为检查该条件应导致执行不同的Docker指令。 - Salem
我的意思是我必须使用参数BUILD_TOOL来确定除了setup.sh之外还必须执行哪些其他指令。例如,在安装MAVEN/ANT之后,我将不得不执行一些常见的指令,并且再次根据BUILD_TOOL来确定需要配置的其他内容,然后是常见的指令,这个模式会重复。根据这种方法,它将变成这样RUN ./setup.sh RUN ./configure.sh RUN ./execute.sh,并且那些包含如你所提到的if/else的文件。希望你明白我的意思。 - DMA
我确定这会起作用,但我不知道它是否是一个好的方法,因为会有很多shell脚本只是为了执行命令(if/else)。因此,我正在寻找更好的方法/解决方案。 - DMA
什么阻止你只使用一个if/else语句,并将每个指令都放在其中(如果ANT则设置Ant;配置Ant;执行Ant;否则设置Maven;配置Maven;执行Maven)? - Salem
是的,我可以做到这一点,但是我有一些通用指令需要执行,无论BUILD_TOOL参数如何。在这种情况下,我必须将这些指令放在if / else块中,并且会导致重复的指令。 - DMA

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接