【问题标题】:Conditional Block in DockerDocker 中的条件块
【发布时间】:2017-03-10 13:06:08
【问题描述】:

我已经使用 docker 有一段时间了。我遇到了一种情况,我需要根据某些条件执行 Dockerfile 中存在的指令。比如这里是Dockerfile的sn-p

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; fiLink,或编写单独的脚本文件,如 this 但正如你所见,我的情况不同。我无法做到这一点,因为我也会有一堆其他的指令,这取决于那个论点。我必须做这样的事情

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

【问题讨论】:

标签: docker dockerfile


【解决方案1】:

如果您不想使用所有这些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 等等。所以我觉得这种方式会很乏味。因此,考虑是否有其他方法可以实现这一点。如果我错了,请纠正我。
  • “因为检查那个条件应该导致不同的docker指令被执行”你能举一个具体的例子吗?
  • 我的意思是我必须使用参数BUILD_TOOL 来确定除了setup.sh 之外还必须执行哪些其他指令。例如,在安装任何一个 MAVEN/ANT 之后,我将不得不执行一些通用指令,并再次基于 BUILD_TOOL 我必须确定需要配置的其他内容,再次是通用指令和模式重复。按照这种方法,它会变成这种方式 RUN ./setup.sh RUN ./configure.sh RUN ./execute.sh 和那些包含 if/else 的文件,正如你上面提到的。希望你明白我想说的。
  • 我确信这会起作用,但我只是不知道这是否是一个好方法,因为会有很多 shell 脚本只是用于执行命令(if/else)。因此正在为此寻找更好的方法/解决方案。
  • 是什么阻止了您在其中的每条指令中只有一个 if/else (if ANT then setupAnt; configureAnt; executeAnt; else setupMaven; configureMaven; executeMaven)?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-13
  • 2021-06-24
相关资源
最近更新 更多