ARG
ARG <name>[=<default value>]
ARG命令定义了一些用户可以在构建时传入的变量,使用docker build
命令使用--build-arg <varname>=<value>
标志。如果用户指定了一个Dockerfile中没有定义的构建参数,那么在构建的输出中会输出警告。
[Warning] One or more build-args [foo] were not consumed.
Dockerfile的作者可以定义一个变量通过使用一次ARG
指令,或者许多变量使用ARG
指令多次。例如,一个合法的Dockerfile:
FROM busybox
ARG user1
ARG buildno
...
Dockerfile的作者可以主动的为ARG
命令的变量设置默认值:
FROM busybox
ARG user1=someuser
ARG buildno=1
...
如果ARG
拥有一个默认值,并且在构建时没有一个值传入,那么构建器会使用那个默认值。
ARG
变量在Dockerfile
中被定义的那一行生效,而不是参数传递或命令行或其他东西。例如,考虑下面的Dockerfile:
1 FROM busybox
2 USER ${user:-some_user}
3 ARG user
4 USER $user
...
第2行的USR
指令中的变量user
的值为some_user
,已经下面的3行。第4行的USR
指令中user
的值为what_user
,what_user
是从命令行中传输过来的值。在ARG
命令进行定义之前,任何使用变量的结果都是空字符串。
注意:不建议使用构建时的变量传入秘钥,如github 秘钥或用户证书等。构建时变量可以被任何可以使用
docker history
的用户看到。
你可以使用ARG
命令或者ENV
命令去指定RUN
中的变量。环境变量使用ENV
命令去指定,可以覆盖ARG
命令定义的同名变量。考虑下面带有ENV
和ARG
命令的Dockerfile。
1 FROM ubuntu
2 ARG CONT_IMG_VER
3 ENV CONT_IMG_VER v1.0.0
4 RUN echo $CONT_IMG_VER
接着构建这个镜像使用下面的命令:
$ docker build --build-arg CONT_IMG_VER=v2.0.1 .
在这种情况下,RUN
指令使用v1.0.0
而不是ARG
设置的v2.0.1
。这与shell脚本中的行为类似,一个局部变量的值会覆盖命令行中传入的值,从环境中解析出来的值或者从定义位置设置的值。
使用上面的例子但是不同的ENV
规范,你可以创建更有用的ARG
和ENV
的配合:
1 FROM ubuntu
2 ARG CONT_IMG_VER
3 ENV CONT_IMG_VER ${CONT_IMG_VER:-v1.0.0}
4 RUN echo $CONT_IMG_VER
不同于ARG
指令,ENV
的值总是会持久的存在构建的镜像当中。考虑一个不使用--build-arg
的docker build。
$ docker build .
使用这个Dockerfile例子,CONT_IMG_VER
会持久化的存储在镜像当中,并且他的值会是v1.0.0
,在第3行被ENV
指令所设置。
在这个例子当中的变量扩展技术允许你通过命令行传入参数,并且在最终的镜像中持久化他们使用ENV
指令。变量扩展只对一些Dockerfile指令支持。
Docker拥有一系列预定义的ARG
变量,你可以使用不需要使用ARG
指令在Dockerfile中指定。
HTTP_PROXY
http_proxy
HTTPS_PROXY
https_proxy
FTP_PROXY
ftp_proxy
NO_PROXY
no_proxy
为了使用这些,从命令行中传输他们:
--build-arg <varname>=<value>
在默认情况下,这些预定义的变量是从docker history
的输出中所排除的。排除他们降低了敏感的认证信息在HTTP_PROXY
中被泄露的风险。
例如,考虑使用--build-arg HTTP_PROXY=http://user:pass@proxy.lon.example.com
进行下面的Dockerfile的构建。
FROM ubuntu
RUN echo "Hello World"
在这种情况下,HTTP_PROXY
的值是不能在docker history
中获取到的,并且不会被缓存下来。如果你希望改变地址,你需要将地址改变为http://user:pass@proxy.sfo.example.com
,后续的构建不会影响在cache中获得结果。
如果你需要覆盖这个特性,那么你需要添加ARG
状态在Dockerfile
当中:
FROM ubuntu
ARG HTTP_PROXY
RUN echo "Hello World"
当使用这个Dockerfile进行构建,HTTP_PROXY
会被存储在docker history
当中,并且改变他的值会使缓存无效。