永久更新 Docker 容器中的 PATH 环境变量

我尝试在文件 ~/.profile/etc/profile中添加 PATH,如下所示。

PATH = $PATH:/required/path

然而,它不工作。然后我尝试添加线显示,这也不工作。

export PATH

它甚至在重新启动容器和主机之后也不工作。

113037 次浏览

Put in your Dockerfile a line ENV PATH xxx see an example in this Dockerfile https://gist.github.com/deepak/5933685

I got the answer for this question in irc chat. Given here for the benefit of anyone who may come across this. Many people have given wrong answers as update the ~/.profile but that did not work. So use the answer below.

Update the file ~/.bashrc for user or update the file /etc/enviroment global for global change which will apply for all users.

In .bashrc export PATH: export PATH=$PATH:/new/path/bin

In enviroment: PATH=$PATH:/new/path/bin

If you want to include a /new/path in the Dockerfile, adding the line:

ENV PATH "$PATH:/new/path"

in Dockerfile should work.

1. The correct answer

The best voted answer suggests to add ENV PATH "$PATH:/new/path" to the Dockerfile, and this should indeed work.

2. So why doesn't it work for me?

As noted in some comments/answers, the solution 1. does not work for some people.

The reason is that the PATH can be overwritten by some script like .bashrc when running the docker container, giving thus the impression that the ENV PATH... did not work, but it theoretically did.

To solve the issue, you need to append to the .bashrc the correct PATH by adding the below command to your Dockerfile:

RUN echo "export PATH=/new/path:${PATH}" >> /root/.bashrc

This is my docker file, on Centos I have extracted and set java home path and it worked for me.

Dockerfile:

FROM  centos:7
RUN yum update -y yum install -y tar
COPY jdk-7u80-linux-x64.tar.gz /opt/
WORKDIR /opt
RUN tar -xvf jdk-7u80-linux-x64.tar.gz
RUN chmod -R 755 jdk1.7.0_80
RUN echo export JAVA_HOME=/opt/jdk1.7.0_80 >> /etc/profile
RUN echo export PATH='$PATH:$JAVA_HOME/bin' >> /etc/profile
ENV JAVA_HOME "/opt/jdk1.7.0_80"
ENV PATH "${JAVA_HOME}/bin:${PATH}"

The difference between interactive and non-interactive shells is not noted. Hence, that's why above solutions sometimes seem to work and sometimes not.

bashrc files typically get skipped for non-interactive shells. For instance in Debian, the /etc/bash.bashrc file very clearly states:

# System-wide .bashrc file for interactive bash(1) shells.


# To enable the settings / commands in this file for login shells as well,
# this file has to be sourced in /etc/profile.


# If not running interactively, don't do anything
[ -z "$PS1" ] && return
  • A RUN command in Dockerfile invokes a non-interactive shell. And the path set by ENV will be taken and bashrc scripts will not run.
  • docker run -it <image> /bin/bash invokes an interactive shell. bashrc will be run and could override anything set in ENV, if the for instance PATH is not defined in the usual PATH=$PATH:/... syntax in any of the bashrc scripts.

In order to be safe and consistent between the 2 modes of operation, one could do in Dockerfile:

ENV PATH /master/go/bin:${PATH}
RUN echo "${PATH}" >> /etc/bash.bashrc

Note that /etc/bash.bashrc is the Debian location and probably is different on other distribution images.