我有dockerfile

FROM centos:7
ENV foo=42

然后我建立它

docker build -t my_docker .

然后运行它。

docker run -it -d  my_docker

是否可以从命令行传递参数,并在Dockerfile中使用if else ?我的意思是

FROM centos:7
if (my_arg==42)
     {ENV=TRUE}
else:
     {ENV=FALSE}

用这个论证来构建。

 docker build -t my_docker . --my_arg=42

当前回答

直接使用“test”二进制代码就可以做到这一点。如果你不想指定一个“else”条件,你也应该使用noop命令“:”,这样docker就不会因为一个非零的返回值错误而停止。

RUN test -z "$YOURVAR" || echo "var is set" && echo "var is not set"
RUN test -z "$YOURVAR" && echo "var is not set" || :
RUN test -z "$YOURVAR" || echo "var is set" && :

其他回答

正如其他人所说,shell脚本会有所帮助。

只是一个额外的情况,恕我直言,值得一提的是(对于无意中发现这里的人来说,寻找一个更简单的情况),那就是环境替换。

Environment variables (declared with the ENV statement) can also be used in certain instructions as variables to be interpreted by the Dockerfile. The ${variable_name} syntax also supports a few of the standard bash modifiers as specified below: ${variable:-word} indicates that if variable is set then the result will be that value. If variable is not set then word will be the result. ${variable:+word} indicates that if variable is set then word will be the result, otherwise the result is the empty string.

对于上述提出的解决方案,有一个有趣的替代方案,它使用单个Dockerfile,每个条件构建只需要调用一次docker构建,并避免bash。

解决方案:

下面的Dockerfile解决了这个问题。复制粘贴,自己试试。

ARG my_arg

FROM centos:7 AS base
RUN echo "do stuff with the centos image"

FROM base AS branch-version-1
RUN echo "this is the stage that sets VAR=TRUE"
ENV VAR=TRUE

FROM base AS branch-version-2
RUN echo "this is the stage that sets VAR=FALSE"
ENV VAR=FALSE

FROM branch-version-${my_arg} AS final
RUN echo "VAR is equal to ${VAR}"

Dockerfile说明:

我们首先得到一个基本图像(在您的例子中是centos:7),并将其放入自己的阶段。基本阶段应该包含在条件之前要做的事情。在那之后,我们还有两个阶段,代表我们的条件的分支:branch-version-1和branch-version-2。我们两个都做了。最终阶段根据my_arg选择其中一个阶段。条件Dockerfile。好了。

运行时输出:

(我把它缩写了一下…)

my_arg = = 2

docker build --build-arg my_arg=2 .
Step 1/12 : ARG my_arg
Step 2/12 : ARG ENV
Step 3/12 : FROM centos:7 AS base
Step 4/12 : RUN echo "do stuff with the centos image"
do stuff with the centos image
Step 5/12 : FROM base AS branch-version-1
Step 6/12 : RUN echo "this is the stage that sets VAR=TRUE"
this is the stage that sets VAR=TRUE
Step 7/12 : ENV VAR=TRUE
Step 8/12 : FROM base AS branch-version-2
Step 9/12 : RUN echo "this is the stage that sets VAR=FALSE"
this is the stage that sets VAR=FALSE
Step 10/12 : ENV VAR=FALSE
Step 11/12 : FROM branch-version-${my_arg}
Step 12/12 : RUN echo "VAR is equal to ${VAR}"
VAR is equal to FALSE

my_arg = = 1

docker build --build-arg my_arg=1 .
...
Step 11/12 : FROM branch-version-${my_arg}
Step 12/12 : RUN echo "VAR is equal to ${VAR}"
VAR is equal to TRUE

感谢Tõnis提供这个惊人的想法!

对于任何试图构建基于Windows的映像的人,您需要访问参数%%的cmd。

# Dockerfile Windows
# ...
ARG SAMPLE_ARG
RUN if %SAMPLE_ARG% == hello_world ( `
    echo hehe %SAMPLE_ARG% `
    ) else ( `
    echo haha %SAMPLE_ARG% `
)
# ...

顺便说一下,ARG声明必须放在FROM之后,否则参数将不可用。

直接使用“test”二进制代码就可以做到这一点。如果你不想指定一个“else”条件,你也应该使用noop命令“:”,这样docker就不会因为一个非零的返回值错误而停止。

RUN test -z "$YOURVAR" || echo "var is set" && echo "var is not set"
RUN test -z "$YOURVAR" && echo "var is not set" || :
RUN test -z "$YOURVAR" || echo "var is set" && :

# FROM前面的ARGs用于图像 ARG IMLABEL=xxxx \ IMVERS = x.x 从$ {IMLABEL}: $ {IMVERS} # FROM后面的ARGs是用于脚本中使用的参数 ARG condition-x RUN if ["$condition-x" = "condition-1"];然后\ 回声“condition 1美元”;\ Elif ["$condition-x" = "condition-1"];然后\ 回声“情况2美元”;\ 其他的 回声“condition-others美元”;\ fi

build -t——build-arg IMLABEL——build-arg IMVERS——build-arg condition-x -f Dockerfile -t image:版本号。