Linux入门教程:Dockerfile参考(15) – ARG指令定义由用户在命令行赋值的变量,如果用户指定了一个构


格式:

ARG <name>[=<default value>]

ARG指令定义了一个变量,能让用户可以在构建期间使用docker build命令和其参数–build-arg =对这个变量赋值。如果用户指定了一个构建参数没有定义在Dockerfile的话,将输出错误。

One or more build-args were not consumed, failing build.

Dockerfile作者可以指定ARG一次定义一个变量,或者指定ARG多次定义多个变量。例如:

FROM busybox ARG user1 ARG buildno ...

Dockerfile作者也可以为这个变量指定一个默认值:

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 ...

使用如下命令构建:

$ docker build --build-arg user=what_user Dockerfile

第2行的USER的值为some_user,因为user变量在第3行才定义。第4行的USER值为what_user,因为user变量在它之前定义了并且在命令行给user变量赋值为what_user。在ARG指令定义变量之前引用这个变量的得,都会得到空值。

警告:不推荐在构建期间的命令行传递密码如github密钥,用户凭证等数据。构建期间设置的变量可以通过docker history命令来查看。

可以使用ARG或ENV指令指定可用于RUN指令的变量。使用ENV定义的环境变量始终会覆盖同一名称的ARG指令定义的变量。例如:

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 Dockerfile

在这种情况中,RUN指令解析CONT_IMG_VER变量的值为v1.0.0而不是ARG设置并由用户传递过来的v2.0.1。
使用上面的示例,但不一样的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 Dockerfile

使用这个Dockerfile示例,CONT_IMG_VER仍然会存在于镜像中,不过它的值会是默认的v1.0.0,当然你也可以在命令行中更改它。
Docker有一组预设置的ARG变量,你不需要在Dockerfile中定义就能够使用它。

HTTP_PROXY http_proxy HTTPS_PROXY https_proxy FTP_PROXY ftp_proxy NO_PROXY no_proxy

要设置这些变量,可以在命令行赋值

--build-arg <varname>=<value>

ARG对构建缓存的影响

ARG变量不像ENV变量始终存在于镜像中。不过ARG变量会以类似的方式对构建缓存产生影响。如果Dockerfile中定义的ARG变量的值与之前定义的变量值不一样,那么就有可能产生“cache miss”。比如RUN指令使用ARG定义的变量时,ARG变量的值变了之后,就会导致缓存失效。

相关内容