ARG¶
指令¶
描述¶
ARG 构建参数,主要是在 build 构建镜像过程中使用。Dockerfile 中的 ARG 指令定义参数名称,以及定义其默认值。该默认值可以在构建命令 docker build
中用 --build-arg <参数名>=<值>
来覆盖修改。
在 Docker 1.13 之前的版本,要求 --build-arg
中使用的参数名,必须在 Dockerfile 中用 ARG 定义过了;换句话说,就是 --build-arg
指定的参数,必须在 Dockerfile 中定义了,如果对应参数没有定义,则会报错退出构建。从 1.13 开始,这种严格的限制被放开,不再报错退出,而是显示警告信息,并继续构建。这对于使用 CI 系统,用同样的构建流程构建不同的 Dockerfile 的时候比较有帮助,避免构建命令必须根据每个 Dockerfile 的内容修改。
ARG 构建参数和 ENV 的效果一样,都是设置环境变量。所不同的是,ARG 所设置的构建环境的环境变量,在将来容器运行时是不会保存在这些环境变量的。但不要因此就使用 ARG 保存密码之类的信息,因为 docker history
还是可以看到所有值的。
Dockerfile 中包含一个或多个ARG指令。例如,以下是有效的Dockerfile:
ARG 默认值¶
ARG指令可以可选地包括一个默认值:
如果 ARG 指令具有默认值,并且在构建时未传递任何值,那么构建器将使用该默认值。
预定义的 ARG¶
Docker 具有一组预定义 ARG 变量,可以在没有定义的情况下使用这些 变量
-
HTTP_PROXY
-
http_proxy
-
HTTPS_PROXY
-
https_proxy
-
FTP_PROXY
-
ftp_proxy
-
NO_PROXY
-
no_proxy
要使用这些参数,只需使用以下标志在命令行中传递它们即可:
默认情况下,这些预定义变量不会出现在 docker history 的输出中,这样可以降低意外泄露 HTTP_PROXY 变量中的敏感身份验证信息的风险。
例如,可以考虑使用以下命令构建以下 Dockerfile
Dockerfile文件:
在这种情况下,HTTP_PROXY 变量的值在不会显示在 docker history 中,也不会被缓存。
如果要更改配置,比如代理服务器已更改为 http://user:pass@proxy.sfo.example.com
,后续的构建也不会获取到之前的缓存信息。
如果您需要覆盖此默认的行为,则可以通过在 Dockerfile 中添加 ARG 的 如下语句来做到这一点:
构建此 Dockerfile 时,HTTP_PROXY
会保留在 docker history
中。
ARG 范围¶
ARG 具有一定的范围。例如,考虑以下Dockerfile:
用户通过调用以下命令来构建此文件:
第2行的 USER 的值为 some_user,因为 user 变量在第3行才定义。第4行的USER值为 what_user,因为user变量在它之前定义了并且在命令行给user变量赋值为 what_user。在 ARG 指令定义变量之前引用这个变量的,都会得到空值。即第二行是无效的,因为在第二行时没有声明user变量,无法使用。
ARG 对缓存的影响¶
ARG 变量不像 ENV 变量始终存在于镜像中。不过 ARG 变量会以类似的方式对构建缓存产生影响。如果 Dockerfile 中定义的 ARG 变量的值与之前定义的变量值不一样,那么就有可能产生“cache miss”。比如RUN指令使用ARG定义的变量时,ARG变量的值变了之后,就会导致缓存失效,即无法获取到该变量。
例如,考虑以下两个Dockerfile:
如果 --build-arg CONT_IMG_VER=<value>
在命令行上指定,则在两种情况下,第2行上的指定都不会导致高速缓存未命中。第3行确实会导致缓存未命中。ARG CONT_IMG_VER
导致RUN行被标识为与正在运行的CONT_IMG_VER=<value>echo hello
相同,因此,如果进行了
考虑同一命令行下的另一个示例:
在此示例中,高速缓存未命中发生在第3行。之所以发生未命中,是因为变量中的变量值ENV引用了该ARG变量,并且该变量是通过命令行更改的。在此示例中,该ENV 命令使 image镜像 包含该值。
如果一条ENV指令覆盖ARG了同名的一条指令,例如Dockerfile:
第3行不会导致缓存未命中,因为值 CONT_IMG_VER 是一个常量(hello)。结果,RUN(第4行)使用的环境变量和值在两次构建之间不会改变。
使用ARG变量¶
可以使用ARG或ENV指令指定可用于RUN指令的变量。使用ENV定义的环境变量始终会覆盖同一名称的ARG指令定义的变量。例如:
然后,假定此映像是使用以下命令构建的:
在这种情况下,该RUN指令将使用v1.0.0而不是ARG用户传递的设置:v2.0.1
此行为类似于Shell脚本,其中局部作用域的变量从其定义的角度覆盖作为参数传递或从环境继承的变量。
使用上面的示例,但使用不同的ENV规范,可以在ARG和ENV指令之间创建更有用的交互:
与ARG指令不同,ENV值始终保留在生成的映像中。考虑不带 --build-arg 标志的Docker构建:
使用此 Dockerfile 示例,CONT_IMG_VER 它仍然保留在映像中,但其值将是指令v1.0.0第3行中的默认设置ENV。
在此示例中,变量扩展技术使您可以从命令行传递参数,并利用 ENV 指令将其保留在最终映像中 。仅有限的一组 Dockerfile 指令支持变量扩展。
全局范围内的平台自动化ARG
仅当使用BuildKit后端时,此功能才可用。
Docker ARG 在执行构建的节点的平台(构建平台)和结果映像的平台(目标平台)上用信息预定义了一组变量。可以使用--platform标志on 来指定目标平台docker build。
以下ARG变量是自动设置的:
-
TARGETPLATFORM-构建结果的平台。例如 linux/amd64,linux/arm/v7,windows/amd64。
-
TARGETOS -TARGETPLATFORM的OS组件
-
TARGETARCH -TARGETPLATFORM的体系结构组件
-
TARGETVARIANT -TARGETPLATFORM的变体组件
-
BUILDPLATFORM -执行构建的节点的平台。
-
BUILDOS -BUILDPLATFORM的OS组件
-
BUILDARCH -BUILDPLATFORM的OS组件
-
BUILDVARIANT -BUILDPLATFORM的OS组件
这些参数是在全局范围内定义的,因此不会在构建阶段或您的RUN命令中自动提供。为了在构建阶段公开这些参数之一,请重新定义它而没有价值。
例如:
Dockerfile中的ARG指令详解¶
文章摘要¶
本文聚焦于Dockerfile中的ARG
指令,深入解析其功能、使用场景以及与其他Dockerfile指令的区别。ARG
指令用于定义构建时的变量,允许用户在构建镜像时动态传递参数,从而实现镜像构建的灵活性和可配置性。
核心内容¶
1. ARG指令的基本语法¶
ARG
指令的基本语法如下:
示例:
在构建过程中,可以通过命令行参数覆盖默认值:2. ARG的作用范围¶
ARG
定义的变量仅在构建阶段有效,不会保留到最终镜像中。- 与
ENV
指令的区别:ENV
定义的变量会持久化到镜像中,而ARG
仅在构建阶段有效。
3. ARG的使用场景¶
- 动态指定镜像版本号:例如
ARG VERSION=1.0
。 - 传递构建时的环境变量:例如
ARG BUILD_ENV=production
。 - 支持多阶段构建中不同阶段的参数传递。
4. ARG与ENV的区别¶
ARG
用于构建时传递参数,ENV
用于运行时设置环境变量。ARG
的值可以通过--build-arg
覆盖,ENV
的值在构建完成后不可更改。
5. ARG的最佳实践¶
- 设置合理的默认值:为
ARG
变量设置合理的默认值,避免构建失败。 - 明确传递构建参数:在构建脚本中明确传递
--build-arg
参数,确保构建的可重复性。 - 避免存储敏感信息:避免在
ARG
中存储敏感信息(如密码),建议使用--secret
或外部工具管理。
与其他章节的区别¶
- 与
ENV
、RUN
、FROM
等其他Dockerfile指令的区别:本章节专注于ARG
指令的详细解析,突出其在构建阶段的独特作用。 - 与“Dockerfile功能详解”章节的区别:本章节更聚焦于
ARG
的具体实现和最佳实践,而非泛泛而谈。 - 与“镜像构建优化”章节的区别:本章节更注重构建时的参数传递机制,而非镜像构建的整体优化策略。
总结¶
ARG
指令是Dockerfile中实现动态构建的关键工具,通过合理使用ARG
,可以显著提升镜像构建的灵活性和可维护性。本章节为读者提供了从基础语法到高级实践的全面指导,帮助开发者在实际项目中高效应用ARG
指令。
关键词¶
- Dockerfile
- ARG指令
- 构建参数
- 动态配置
- 多环境构建
- 构建阶段变量
这篇Markdown格式的技术文档详细介绍了Dockerfile中的ARG
指令,涵盖了其基本语法、作用范围、使用场景、与ENV
的区别、最佳实践以及与其他章节的区别。通过这篇文档,读者可以全面了解并掌握如何在Dockerfile中高效使用ARG
指令。