在Dockerfile中,如何更新PATH环境变量?

ILi*_*cos 295 docker dockerhub

我有一个从源代码下载和构建GTK的dockerfile,但以下行没有更新我的图像的环境变量:

RUN PATH="/opt/gtk/bin:$PATH"
RUN export PATH
Run Code Online (Sandbox Code Playgroud)

我读到我应该使用ENV来设置环境值,但以下指令似乎也不起作用:

ENV PATH /opt/gtk/bin:$PATH

这是我的整个Dockerfile:

FROM ubuntu
RUN apt-get update
RUN apt-get install -y golang gcc make wget git libxml2-utils libwebkit2gtk-3.0-dev libcairo2 libcairo2-dev libcairo-gobject2 shared-mime-info libgdk-pixbuf2.0-* libglib2-* libatk1.0-* libpango1.0-* xserver-xorg xvfb

# Downloading GTKcd
RUN wget http://ftp.gnome.org/pub/gnome/sources/gtk+/3.12/gtk+-3.12.2.tar.xz
RUN tar xf gtk+-3.12.2.tar.xz
RUN cd gtk+-3.12.2

# Setting environment variables before running configure
RUN CPPFLAGS="-I/opt/gtk/include"
RUN LDFLAGS="-L/opt/gtk/lib"
RUN PKG_CONFIG_PATH="/opt/gtk/lib/pkgconfig"
RUN export CPPFLAGS LDFLAGS PKG_CONFIG_PATH
RUN ./configure --prefix=/opt/gtk
RUN make
RUN make install

# running ldconfig after make install so that the newly installed libraries are found.
RUN ldconfig

# Setting the LD_LIBRARY_PATH environment variable so the systems dynamic linker can find the newly installed libraries.
RUN LD_LIBRARY_PATH="/opt/gtk/lib"

# Updating PATH environment program so that utility binaries installed by the various libraries will be found.
RUN PATH="/opt/gtk/bin:$PATH"
RUN export LD_LIBRARY_PATH PATH

# Collecting garbage
RUN rm -rf gtk+-3.12.2.tar.xz

# creating go code root
RUN mkdir gocode
RUN mkdir gocode/src
RUN mkdir gocode/bin
RUN mkdir gocode/pkg

# Setting the GOROOT and GOPATH enviornment variables, any commands created are automatically added to PATH
RUN GOROOT=/usr/lib/go
RUN GOPATH=/root/gocode
RUN PATH=$GOPATH/bin:$PATH
RUN export GOROOT GOPATH PATH
Run Code Online (Sandbox Code Playgroud)

Hom*_*tra 477

您可以使用环境更换Dockerfile如下:

ENV PATH="/opt/gtk/bin:${PATH}"
Run Code Online (Sandbox Code Playgroud)

  • ```ENV PATH="/opt/gtk/bin:${PATH}"``` 可能与 ```ENV PATH="/opt/gtk/bin:$PATH"``` 不同带大括号的 可能会为您提供主机的 PATH。文档并没有表明情况会如此,但我观察到确实如此。检查起来很简单,只需执行 ```RUN echo $PATH``` 并将其与 ```RUN echo ${PATH}``` 进行比较 (25认同)
  • 这样可行!请注意`=`它需要没有空格.如果在`=`旁边添加空格,就像这样`ENV PATH ="/ opt/gtk/bin:$ {PATH}"`将破坏你的$ PATH (19认同)
  • @IgorGanapolsky不在此实例中,因为它指定了单个变量.但是,它不会造成伤害,并且在指定多个变量时是必需的.有关详细信息,请参阅[ENV文档](https://docs.docker.com/engine/reference/builder/#env). (13认同)
  • 是```等于必要的标志? (11认同)
  • 这不会更新附加主机的“$PATH”的映像吗? (6认同)
  • @dankirkd 这绝对是疯狂的。我决定提出一个有关此问题的问题:https://github.com/moby/moby/issues/42863 如果您愿意,请随意添加更多信息。 (3认同)
  • @dankirkd 这是一个非常有用的观察,值得+100 票,或者本身就是一个答案。谢谢。 (2认同)

ILi*_*cos 43

虽然Gunter发布的答案是正确的,但它与我已发布的内容没有什么不同.问题不是ENV指令,而是后续指令RUN export $PATH

一旦ENV在Dockerfile中声明了环境变量,就无需导出环境变量.

一旦RUN export ...删除线条,我的图像就会成功构建

  • `RUN A=B`、`RUN export A` 和 `RUN export A=B` 是有效的 shell 命令,但影响 _only_ 跟在同一个 `RUN` 指令中的命令的环境(但没有给出)。同样,如果你有 `RUN export PATH=/foo; 程序1; prog2;`(在同一个 RUN 中),PATH 修改会影响 `prog1` 和 `prog2`。因此,`RUN export $PATH` 是一个 noop(因为没有程序使用该修改后的环境)并且该指令是否存在应该没有区别。“Gunter”是指[这个答案](/sf/answers/2711978181/)吗? (5认同)

dan*_*rkd 15

[我在回复所选答案时提到了这一点,但建议使其更加突出作为自己的答案]

应该注意的是

ENV PATH="/opt/gtk/bin:${PATH}" 
Run Code Online (Sandbox Code Playgroud)

可能不一样

ENV PATH="/opt/gtk/bin:$PATH" 
Run Code Online (Sandbox Code Playgroud)

前者带有大括号,可能会为您提供主机的 PATH。文档并未暗示会是这种情况,但我观察到确实如此。这很容易检查只是做RUN echo $PATH并将其与RUN echo ${PATH}

  • 我刚刚在 Mac 上用 20.10.2 尝试过,两者不一样。${PATH} 包含我的笔记本电脑上的路径(例如 /Library/... 和 /Users/...),而 $PATH 仅反映容器上下文中的路径。 (3认同)
  • 最新的 https://docs.docker.com/engine/reference/builder/#environment-replacement 说“环境变量在 Dockerfile 中用 $variable_name 或 ${variable_name} 表示。它们被同等对待” (3认同)
  • 只是试图验证这个断言,两个命令给出了相同的输出。使用 Docker 20.10.2。 (2认同)
  • 嗯......“等效”并不一定意味着“完全相同”。我建议任何有兴趣的人检查 $PATH 和 ${PATH} 是否如此。20.10.6 仍然具有不同的行为。 (2认同)

Tho*_*aux 10

不鼓励这样做(如果您想创建/分发干净的 Docker 映像),因为该PATH变量是由/etc/profile脚本设置的,因此可以覆盖该值。

head /etc/profile

if [ "`id -u`" -eq 0 ]; then
  PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
else
  PATH="/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games"
fi
export PATH
Run Code Online (Sandbox Code Playgroud)

在 Dockerfile 的末尾,您可以添加:

RUN echo "export PATH=$PATH" > /etc/environment
Run Code Online (Sandbox Code Playgroud)

因此为所有用户设置了 PATH。

  • 根据 [this Ubuntu documentation](https://help.ubuntu.com/community/EnvironmentVariables#A.2Fetc.2Fenvironment),`/etc/environment` 是赋值表达式列表,不是脚本,不支持变量扩展,因此 `RUN` 语法不太可能起作用。 (6认同)
  • 是的,它将被扩展并且`export PATH=<some path>` 将被写入`/etc/environment`,这仍然是不正确的,因为该文件不是脚本而是`<var name>=<value 的列表>`。除非您的系统支持规范之外的某些黑魔法,否则 `export` 可能会使其失败。 (3认同)