Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/docker/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Dockerfile:在单行中设置多个环境变量_Docker_Dockerfile - Fatal编程技术网

Dockerfile:在单行中设置多个环境变量

Dockerfile:在单行中设置多个环境变量,docker,dockerfile,Docker,Dockerfile,我的印象是,环境变量可以设置在一行上,如下所示,以尽量减少中间图像 FROM alpine:3.6 ENV RUBY_MAJOR 2.4 \ RUBY_VERSION 2.4.1 \ RUBY_DOWNLOAD_SHA256 4fc8a9992de3e90191de369270ea4b6c1b171b7941743614cc50822ddc1fe654 \ RUBYGEMS_VERSION 2.6.12 \ BUNDLER_VERSION 1.15.3 但是,运

我的印象是,环境变量可以设置在一行上,如下所示,以尽量减少中间图像

FROM alpine:3.6
ENV RUBY_MAJOR 2.4 \
    RUBY_VERSION 2.4.1 \
    RUBY_DOWNLOAD_SHA256 4fc8a9992de3e90191de369270ea4b6c1b171b7941743614cc50822ddc1fe654 \
    RUBYGEMS_VERSION 2.6.12 \
    BUNDLER_VERSION 1.15.3
但是,运行基于此代码段的容器并调用
|set | grep RU
时,我发现变量没有被单独分配,而是被组合成一个字符串

RUBY_MAJOR='2.4     RUBY_VERSION 2.4.1     RUBY_DOWNLOAD_SHA256 4fc8a9992de3e90191de369270ea4b6c1b171b7941743614cc50822ddc1fe654     RUBYGEMS_VERSION 2.6.12     BUNDLER_VERSION 1.15.3'
但是,如果我显式地将每个变量设置为如下所示,则会得到预期的输出,并且在调用变量时不会出现错误

ENV RUBY_MAJOR 2.4
ENV RUBY_VERSION 2.4.1
ENV RUBY_DOWNLOAD_SHA256 4fc8a9992de3e90191de369270ea4b6c1b171b7941743614cc50822ddc1fe654
ENV RUBYGEMS_VERSION 2.6.12
ENV BUNDLER_VERSION 1.15.3

问题:是否可以在一行上组合环境变量的设置?如果是,我会怎么做?这是一种好的做法吗?

有两种格式可用于指定环境。如果您需要单个变量,则可以使用以下格式

ENV X Y
这将把X指定为
Y

ENX X Y Z
这将把X指定为
Y Z

如果需要分配多个环境变量,则使用其他格式

ENV X=Y Z=A
这会将X指定为
Y
,将Z指定为
A
。所以你的
Dockerfile
应该是

FROM alpine:3.6
ENV RUBY_MAJOR=2.4 \
    RUBY_VERSION=2.4.1 \
    RUBY_DOWNLOAD_SHA256=4fc8a9992de3e90191de369270ea4b6c1b171b7941743614cc50822ddc1fe654 \
    RUBYGEMS_VERSION=2.6.12 \
    BUNDLER_VERSION=1.15.3

RUN env

您不需要担心许多
ENV
命令,每个命令都会为Dockerfile创建的最终图像创建一个新的中间层

尽量减少层数 在Docker 17.05之前,甚至在Docker 1.10之前,尽量减少图像中的层数非常重要。以下改进缓解了这一需求:

  • 在Docker 1.10及更高版本中,只有
    运行
    复制
    、和
    添加
    指令才能创建层。其他指令创建临时中间映像,不再直接增加生成的大小

  • Docker 17.05及更高版本添加了对的支持,允许您仅将所需的工件复制到最终图像中。这允许您在中间构建阶段包括工具和调试信息,而不增加最终映像的大小


您还可以将其与引号和现有环境变量的扩展相结合。例如,通常希望将路径扩展为一组环境变量的一部分:
ENV path=“$path:/app”\APPVAR=“foo”
奇怪的是,我尝试在第二个变量中使用第一个变量,但它只是解析为空字符串,不管是一行还是多行-line@milosmns是的,我注意到牙齿的行为需要建立arguments@milosmns@kiran challa为了解释Tarun的评论,在给定的
ENV
命令完成之前,不会设置在该命令上声明的任何变量,因此行为符合预期(在任何基于*nix的系统上尝试
echo$V_NOT_SET
)。输入构建参数。作为旁注,
export V_NOT_SET=“hello”echo$V_NOT_SET
也只会导致空白;在这之前添加
export
没有帮助;插入
&
(又称
)在
导出
回显
之间,将导致回显
hello
,因为现在需要在评估第二个命令之前完成第一个命令。这是不正确的,因为:@Tomanow这是docker文档的直接引用(请参见链接),但我认为混淆之处在于ENV创建的层是“临时”,我认为这意味着在某一点上挤压到不同的层中,但这只是对实现的猜测。从我使用docker 19
ENV
lines进行的测试来看,在构建图像时,不会在图像中创建层,它会说“删除中间容器”“,然后用dive检查图层,我可以看到没有为
ENV
创建图层。虽然ENV图层被压扁很好,但它们仍然必须首先创建,这可能需要在我的笔记本电脑上花费一段时间(这不寻常吗?),所以我认为无论如何还是走多行路线比较好,这样可以节省构建时间。@ChinotoVokro说的……图层确实被创建了,然后被破坏了……但这是一件痛苦的事情。