我有一个从源代码下载和构建 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
尽管 Gunter 发布的答案是正确的,但它与我已经发布的并没有什么不同。问题不是 ENV
指令,而是后续指令 RUN export $PATH
在 Dockerfile 中通过 ENV
声明环境变量后,无需导出环境变量。
删除 RUN export ...
行后,我的图像就成功构建了
RUN A=B
、RUN export A
和 RUN export A=B
是有效的 shell 命令,但仅影响同一 RUN
指令后面的命令的环境(但没有给出)。同样,如果您有 RUN export PATH=/foo; prog1; prog2;
(在同一个 RUN 中),PATH 修改会影响 prog1
和 prog2
。因此,RUN export $PATH
是一个 noop(因为没有程序使用该修改后的环境),并且该指令是否存在应该没有区别。 “Gunter”是指this answer吗?
[我在回应所选答案时提到了这一点,但有人建议将其作为自己的答案更加突出]
应当指出的是
ENV PATH="/opt/gtk/bin:${PATH}"
可能不一样
ENV PATH="/opt/gtk/bin:$PATH"
前者带有大括号,可能会为您提供主机的路径。文档并未暗示会出现这种情况,但我观察到确实如此。这很容易检查,只需执行 RUN echo $PATH
并将其与 RUN echo ${PATH}
进行比较
不鼓励这样做(如果您想创建/分发干净的 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 是为所有用户设置的。
export PATH=<some path>
将被写入 /etc/environment
,这仍然不正确,因为该文件不是脚本而是 <var name>=<value>
的列表。 export
可能会使其失败,除非您的系统支持规范之外的某些黑魔法。
/etc/profile
或 /etc/environment
,因此更改这些脚本通常是无效的。
=
是否需要等号?=
。如果您像这样在=
旁边添加空格ENV PATH = "/opt/gtk/bin:${PATH}"
将导致您的 $PATH 崩溃$PATH
的图像吗?ENV PATH="/opt/gtk/bin:${PATH}"
可能与ENV PATH="/opt/gtk/bin:$PATH"
不同,前者带有大括号,可能会为您提供主机的 PATH。文档并未暗示会出现这种情况,但我观察到确实如此。这很容易检查只需执行RUN echo $PATH
并将其与RUN echo ${PATH}
进行比较