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


388

我有一个可以从源代码下载并构建GTK的dockerfile,但是以下行并未更新映像的环境变量:

RUN PATH="/opt/gtk/bin:$PATH"
RUN export PATH

我读到我应该使用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

1
LD_LIBRARY_PATH和PATH应该使用ENV而不是导出来设置。您也是LD_LIBRARY_PATH不应该指向PATH !。删除Dockerfile中的文件不会使图像变小,请检查Centurylinklabs.com/optimizing-docker-images/?hvid=4wO7Yt
哈维尔·卡斯特利亚诺斯

当前的dockerfile是有效的吗?
王晖

@HuiWang可能不会。它是在1.5年前编写的,此后发生了很多变化。只要确保您合并了所选答案中描述的更改即可。
ILikeTacos

Answers:


608

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

ENV PATH="/opt/gtk/bin:${PATH}"

14
=等号是否必要?
IgorGanapolsky

16
@IgorGanapolsky在这种情况下不是,因为它指定了单个变量。但是,它没有问题,并且在指定多个变量时是必需的。有关更多详细信息,请参见ENV文档
霍姆·兹瓦格斯特拉

30
那个有效!请注意=它必须没有空格。如果您在=此旁边添加空格,ENV PATH = "/opt/gtk/bin:${PATH}"将破坏您的$ PATH
Diego Juliao

2
这不会更新带有主机的图像$PATH吗?
emmdee

2
ENV PATH="/opt/gtk/bin:${PATH}"可能与ENV PATH="/opt/gtk/bin:$PATH"前者大括号不同,后者可能为您提供主机的PATH。文档并没有建议是这种情况,但是我观察到确实如此。这很容易检查,只需RUN echo $PATH将其与RUN echo ${PATH}
dankirkd

49

尽管Gunter发布的答案是正确的,但与我已经发布的答案没有什么不同。问题不是ENV指令,而是后续指令RUN export $PATH

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

一旦RUN export ...线路被拆除,我的形象被成功建立


4
RUN A=B,,RUN export ARUN export A=B是有效的Shell命令,但影响遵循同一RUN指令的命令的环境(但未给出)。同样,如果您具有RUN export PATH=/foo; prog1; prog2;(在同一RUN中),则PATH修改将影响prog1prog2。因此,RUN export $PATH是noop(因为没有程序使用该修改后的环境),并且无论该指令是否存在,都应该没有区别。通过“冈特”,你的意思是这个答案
init_js '19

解决方法实际上是使用ENV指令而不是RUN更改PATH值。然后,这些变化将在docker构建器调用以下RUN时保留下来。
init_js '19

5

不建议这样做(如果要创建/分发干净的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

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

RUN echo "export PATH=$PATH" > /etc/environment

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


4
根据此Ubuntu文档/etc/environment是赋值表达式的列表,而不是脚本,并且不支持变量扩展,因此RUN语法不太可能起作用。
Nicolas Lefebvre,

3
是的,它将被扩展并被export PATH=<some path>写入/etc/environment,这仍然是不正确的,因为该文件不是脚本而是的列表<var name>=<value>export除非您的系统支持规范之外的某些黑魔法,否则它很可能会失败。
Nicolas Lefebvre
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.