关于docker:Dockerfile if else条件与外部参数

Dockerfile if else condition with external arguments

我有dockerfile

1
2
FROM centos:7
ENV foo=42

然后我建立它

1
docker build -t my_docker .

和运行它。

1
docker run -it -d  my_docker

它可以通过命令行参数和使用从它在dockerfile if else?我的意思什么样

1
2
3
4
5
FROM centos:7
if (my_arg==42)
     {ENV=TRUE}
else:
     {ENV=FALSE}

这一论点和编译。

1
 docker build -t my_docker . --my_arg=42


它可能看起来不那么干净,但您可以将dockerfile(条件)设置为如下:

1
2
3
FROM centos:7
ARG arg
RUN if ["x$arg" ="x" ] ; then echo Argument not provided ; else echo Argument is $arg ; fi

然后将图像构建为:

docker build -t my_docker . --build-arg arg=45

docker build -t my_docker .


根据build命令文档,有一个名为--build-arg的参数。

https://docs.docker.com/engine/reference/commandline/build/设置生成时间变量build arg

示例用法docker build --build-arg HTTP_PROXY=http://10.20.30.2:1234 .

依我看,这是你需要的:)


出于某种原因,这里的大多数答案对我没有帮助(可能与我在dockerfile中的from image相关)

所以我宁愿在我的工作区创建一个bash script--build-arg组合,以便在docker构建时处理if语句,检查参数是否为空。

BASH脚本:

1
2
3
4
5
6
7
8
9
#!/bin/bash -x

if test -z $1 ; then
    echo"The arg is empty"
    ....do something....
else
    echo"The arg is not empty: $1"
    ....do something else....
fi

Dockerfile:

1
2
3
4
5
6
FROM ...
....
ARG arg
COPY bash.sh /tmp/  
RUN chmod u+x /tmp/bash.sh && /tmp/bash.sh $arg
....

码头工人建造:

1
docker build --pull -f"Dockerfile" -t $SERVICE_NAME --build-arg arg="yes" .

备注:这将转到bash脚本中的else(false)

1
docker build --pull -f"Dockerfile" -t $SERVICE_NAME .

备注:这将提交给国际单项体育联合会(真)

编辑1:

经过几次尝试,我找到了下面的文章和这篇文章这有助于我理解两件事:

1)arg before-from在生成之外

2)默认shell是/bin/sh,这意味着if-else在Docker构建中工作有点不同。例如,您只需要一个"="而不是"=="来比较字符串。

所以你可以在Dockerfile里做这个。

1
2
ARG argname=false   #default argument when not provided in the --build-arg
RUN if ["$argname" ="false" ] ; then echo 'false'; else echo 'true'; fi

docker build中:

1
docker build --pull -f"Dockerfile" --label"service_name=${SERVICE_NAME}" -t $SERVICE_NAME --build-arg argname=true .

只需直接使用"test"二进制文件即可。您还应该使用noop命令":"如果不想指定"else"条件,那么docker不会因非零返回值错误而停止。

1
2
3
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.


使用bash脚本和alpine/centos

文档文件

1
2
3
4
5
6
7
FROM alpine  #just change this to centos

ARG MYARG=""
ENV E_MYARG=$MYARG

ADD . /tmp
RUN chmod +x /tmp/script.sh && /tmp/script.sh

脚本

1
2
3
4
5
6
7
#!/usr/bin/env sh

if [ -z"$E_MYARG" ]; then
    echo"NO PARAM PASSED"
else
    echo $E_MYARG
fi

通过ARG:docker build -t test --build-arg MYARG="this is a test" .

1
2
3
4
5
6
7
....
Step 5/5 : RUN chmod +x /tmp/script.sh && /tmp/script.sh
 ---> Running in 10b0e07e33fc
this is a test
Removing intermediate container 10b0e07e33fc
 ---> f6f085ffb284
Successfully built f6f085ffb284

无精氨酸:docker build -t test .

1
2
3
4
5
6
....
Step 5/5 : RUN chmod +x /tmp/script.sh && /tmp/script.sh
 ---> Running in b89210b0cac0
NO PARAM PASSED
Removing intermediate container b89210b0cac0
....


如果您希望动态构建图像,那么您可能应该使用构建脚本来实现。

Docker已经为许多语言提供了sdk,这些语言通常包括一个构建调用,允许您提供任意字符串或要构建的Dockerfile。

例如,使用Ruby:

1
2
3
4
5
6
7
require 'docker'

val = my_arg == 42 ?"TRUE" :"FALSE"

# Create an Image from a Dockerfile as a String.
Docker::Image.build("FROM centos:7
ENV MY_ENV=" + val)