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

Bri*_*son 52 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
Run Code Online (Sandbox Code Playgroud)

但是,运行基于此代码段的容器并调用# 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'
Run Code Online (Sandbox Code Playgroud)

但是,如果我显式设置每个变量如下,我得到预期的输出,并且在调用变量时没有错误.

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
Run Code Online (Sandbox Code Playgroud)

问题:是否可以将环境变量的设置组合在一条线上?如果是这样,我该怎么做?这是一个好习惯吗?

Tar*_*ani 94

指定环境有两种格式.如果您需要单个变量,那么您将在格式之下

ENV X Y
Run Code Online (Sandbox Code Playgroud)

这将指定X为 Y

ENX X Y Z
Run Code Online (Sandbox Code Playgroud)

这将指定X为 Y Z

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

ENV X=Y Z=A
Run Code Online (Sandbox Code Playgroud)

这将指定X as Y和Z as 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
Run Code Online (Sandbox Code Playgroud)

  • 奇怪的是,我尝试在第二个var中使用第一个var,它只是解析为空字符串,无论是一行还是多行 (2认同)
  • @milosmns @kiran-challa 为了阐述 Tarun 的评论,在给定的“ENV”命令上声明的任何变量在命令完成之前都不会被设置,因此行为符合预期(在任何基于 *nix 的系统上尝试“echo $V_NOT_SET”)系统)。输入构建参数。附带说明一下,`export V_NOT_SET="hello" echo $V_NOT_SET` 也只会产生空格;在此之前添加“export”并没有帮助;在“export”和“echo”之间插入“&&”(又名“AND_IF”)将导致“hello”被回显,因为它现在需要在评估第二个命令之前完成第一个命令。 (2认同)

Mik*_*ert 11

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

来自编写Dockerfile的最佳实践

减少层数

在Docker 17.05之前,甚至在Docker 1.10之前,甚至更多,减少映像中的层数非常重要。以下改进减轻了这种需求:

  • 在泊坞窗1.10和更高,只有RUNCOPYADD指令创建图层。其他说明创建临时的中间映像,并且不再直接增加构建的大小。

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

  • 虽然 ENV 层被压缩很好,但它们仍然必须首先创建,这在我的笔记本电脑上可能需要一段时间(这不寻常吗?),所以我认为最好还是采用多线路线来节省时间构建时间。 (4认同)
  • 从我对docker 19进行的测试中,“ ENV”行未在映像中创建图层,在构建映像时显示“正在移除中间容器”,然后在进行潜水检查时发现,没有为“ ENV”创建任何图层。 (3认同)
  • 根据链接的文章(最佳实践...):“每个 ENV 行都会创建一个新的中间层,就像 RUN 命令一样。” (3认同)