ChatGPT解决这个技术问题 Extra ChatGPT

如何在 Dockerfile 中定义变量?

在我的 Dockerfile 中,我想定义以后可以在 Dockerfile 中使用的变量。

我知道 ENV 指令,但我不希望这些变量成为环境变量。

有没有办法在 Dockerfile 范围内声明变量?

ARG 没有定义可以在 dockerfile 中使用的 var。您必须将其与 ENV 命令配合才能获得所需的内容; ARG 富; ENV FOO=$foo; COPY 文件 $foo (抱歉格式错误,我想不可能从电话中执行代码块和多行)

K
Kumar Saurabh

您可以使用 ARG - 请参阅 https://docs.docker.com/engine/reference/builder/#arg

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

可以在构建期间与 COPY 一起使用(例如,复制特定文件夹等标签特定内容)例如:

ARG MODEL_TO_COPY
COPY application ./application
COPY $MODEL_TO_COPY ./application/$MODEL_TO_COPY

在构建容器时:

docker build --build-arg MODEL_TO_COPY=model_name -t <container>:<model_name specific tag> .

它似乎不适用于 COPY 命令。 docs.docker.com/engine/reference/builder/#arg
O
Ortomala Lokni

要回答您的问题:

在我的 Dockerfile 中,我想定义以后可以在 Dockerfile 中使用的变量。

你可以定义一个变量:

ARG myvalue=3

等号周围不允许有空格。

稍后将其用于:

RUN echo $myvalue > /test

V
VonC

据我所知,只有 ENV 允许这样做,如“Environment replacement”中所述

环境变量(使用 ENV 语句声明)也可以在某些指令中用作要由 Dockerfile 解释的变量。

它们必须是环境变量,才能在 docker build 为 Dockerfile 的每一行创建的每个新容器中重新声明。

换句话说,这些变量不是直接在 Dockerfile 中解释,而是在为 Dockerfile 行创建的容器中解释,因此使用环境变量。

这一天,我同时使用 ARG (docker 1.10+, and docker build --build-arg var=value) 和 ENV
单独使用 ARG 意味着您的变量在构建时可见,在运行时。

我的 Dockerfile 通常有:

ARG var
ENV var=${var}

在您的情况下,ARG 就足够了:我通常使用它来设置 http_proxy 变量,这是 docker build 在构建时访问互联网所需的。

Christopher Kingthe comments 中添加:

小心! ARG 变量仅在“使用它的阶段”的范围内,需要为每个阶段重新声明。

他指出Dockerfile / scope

ARG 变量定义从它在 Dockerfile 中定义的行开始生效,而不是从参数在命令行或其他地方的使用开始生效。例如,考虑这个 Dockerfile: FROM busybox USER ${user:-some_user} ARG user USER $user # ... 用户通过调用 docker build --build-arg user=what_user 来构建这个文件。第 2 行的 USER 评估为 some_user,因为用户变量在随后的第 3 行中定义。第 4 行的 USER 评估为 what_user,因为用户已定义,并且 what_user 值已在命令行上传递。在通过 ARG 指令定义之前,对变量的任何使用都会导致空字符串。 ARG 指令在定义它的构建阶段结束时超出范围。要在多个阶段中使用 arg,每个阶段都必须包含 ARG 指令。


小心! ARG 变量仅在“使用它的阶段”的范围内,需要为每个阶段重新声明! docs.docker.com/engine/reference/builder/#scope
@ChristopherKing 谢谢你的反馈,很好。我已在答案中包含您的评论和参考,以提高知名度。
E
Evgeny Chernyavskiy

如果该变量在同一 RUN 指令中重复使用,则可以简单地设置一个 shell 变量。我真的很喜欢他们用 official Ruby Dockerfile 解决这个问题的方式。


很好的答案。虽然您应该尽可能使用 ARG,但有时您需要分配和重用动态变量。示例:RUN foo=$(date) && echo $foo
u
user2719152

您可以使用 ARG variable defaultValue,在运行命令期间您甚至可以使用 --build-arg variable=value 更新此值。要在 docker 文件中使用这些变量,您可以在运行命令中将它们称为 $variable

注意:这些变量可用于 RUN echo $variable 等 Linux 命令,它们不会保留在映像中。


这是更好的答案,因为默认值是意图的关键
语法需要更新为 ARG variable=defaultvalue 而不是 ARG variable defaultvalue
E
Ervadac

迟到了,但如果你不想暴露环境变量,我想这样做更容易:

RUN echo 1 > /tmp/__var_1
RUN echo `cat /tmp/__var_1`
RUN rm -f /tmp/__var_1

我最终这样做是因为我们在 aws codeartifact 中托管私有 npm 包:

RUN aws codeartifact get-authorization-token --output text > /tmp/codeartifact.token
RUN npm config set //company-123456.d.codeartifact.us-east-2.amazonaws.com/npm/internal/:_authToken=`cat /tmp/codeartifact.token`
RUN rm -f /tmp/codeartifact.token

这里 ARG 不能工作,我不想使用 ENV 因为我不想将此令牌暴露给其他任何东西