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 19ENV
lines进行的测试来看,在构建图像时,不会在图像中创建层,它会说“删除中间容器”“,然后用dive检查图层,我可以看到没有为ENV
创建图层。虽然ENV图层被压扁很好,但它们仍然必须首先创建,这可能需要在我的笔记本电脑上花费一段时间(这不寻常吗?),所以我认为无论如何还是走多行路线比较好,这样可以节省构建时间。@ChinotoVokro说的……图层确实被创建了,然后被破坏了……但这是一件痛苦的事情。