语法

ARG <name>[=<default value>]

作用 和 描述

ARG 指令使用 --build-arg = 标志定义一个变量,用户可以使用 docker build 命令在构建时将该变量传递给构建器。如果用户指定了未在 Dockerfile 中定义的构建参数,则构建会输出告警。

[Warning] One or more build-args [foo] were not consumed.

Dockerfile 可以包含一个或多个 ARG 指令。例如,以下是有效的 Dockerfile:

FROM busybox
ARG user1
ARG buildno
...

警告:
建议不要使用构建时变量来传递 github 密钥,用户凭证等秘密。使用 docker history 命令可以使镜像的任何用户都可以看到构建时变量值。

默认值(Default values)

ARG 指令可以选择包含默认值:

FROM busybox
ARG user1=someuser
ARG buildno=1
...

如果 ARG 指令具有默认值,并且在构建时没有传递值,则构建器将使用默认值。

Scope

ARG 变量定义从 Dockerfile 中定义的行开始生效,而不是从命令行或其它地方的参数使用。例如,考虑这个 Dockerfile:

1 FROM busybox
2 USER ${user:-some_user}
3 ARG user
4 USER $user
...

用户通过调用以下内容构建此文件:

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

第 2 行的 USER 评估为 some_user,因为在后续第 3 行定义了用户变量。第 4 行的 USER 在定义用户时评估为 what_user,并在命令行上传递 what_user 值。在通过 ARG 指令定义之前,对变量的任何使用都会导致空字符串。
ARG 指令在构建阶段结束时超出范围。要在多个阶段中使用 arg,每个阶段必须包含 ARG 指令。

FROM busybox
ARG SETTINGS
RUN ./run/setup $SETTINGS

FROM busybox
ARG SETTINGS
RUN ./run/other $SETTINGS

使用 ARG 变量(Using ARG variables)

你可以使用 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 指令之间创建更有用的交互,例如将 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 构建:

$ docker build .

使用此 Dockerfile 示例,CONT_IMG_VER 仍然保留在镜像中,但其值为 v1.0.0,因为它是 ENV 指令在第 3 行中的默认设置。
本例中的变量扩展技术允许你从命令行传递参数,并通过利用 ENV 指令将它们保存在最终镜像中。只有一组有限的 Dockerfile 指令支持变量扩展。

预定义的 ARG(Predefined ARGs)

Docker 有一组预定义的 ARG 变量,你可以在 Dockerfile 中使用而无需相应的 ARG 指令。

  • 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 构建以下 Dockerfile HTTP_PROXY=http://user:pass@proxy.lon.example.com

FROM ubuntu
RUN echo "Hello World"

在这种情况下,HTTP_PROXY 变量的值在 docker 历史记录中不可用,并且不会被缓存。如果要更改位置,并且代理服务器已更改为http://user:pass@proxy.sfo.example.com,则后续构建不会导致缓存未命中。

如果你需要覆盖此行为,则可以通过在 Dockerfile 中添加 ARG 语句来执行此操作,如下所示:

FROM ubuntu
ARG HTTP_PROXY
RUN echo "Hello World"

构建此 Dockerfile 时,HTTP_PROXY 将保留在 docker 历史记录中,并且更改其值会使构建缓存无效。
@TODO

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐