122

I tried adding to the PATH in the files ~/.profile and /etc/profile as follow.

PATH = $PATH:/required/path

However, it does not work. Then I tried with adding the line show, which did not work either.

export PATH

It did not work even after restarting the container and the host both.

jub0bs
  • 60,866
  • 25
  • 183
  • 186
user859375
  • 3,529
  • 5
  • 21
  • 22
  • The question was after creating the container and made some modifications. Not while creating the container using Docker configuration file. – user859375 Mar 03 '15 at 13:19

6 Answers6

200

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

ENV PATH "$PATH:/new/path"

in Dockerfile should work.

Jianxin Gao
  • 2,717
  • 2
  • 19
  • 32
  • 11
    Note that the quotes are important. – orodbhen Oct 06 '17 at 13:54
  • 1
    This works but not for all users. Any idea how to make it available for everyone? – MrUpsidown Mar 07 '18 at 19:00
  • 1
    It's not possible with ENV, instead you'll have to use something similar to /etc/environment: https://github.com/moby/moby/issues/15383 – kossmoboleat Dec 03 '18 at 17:22
  • 1
    This worked fine for me. I needed to add a JDK to an image (I couldn't just use apt install, had to be downloaded and extracted separately), so I added ENV JAVA_HOME "/path/to/jdk" and ENV PATH "${JAVA_HOME}/bin:${PATH}". Once I rebuilt the image, the JDK was available to the build user. – Spanky Quigman Dec 28 '18 at 19:57
  • is there a special way to do this in LSF from IBM? – Brian Wiley Mar 15 '21 at 21:36
  • This does not work if USER is specified. echo $PATH shows the correct path, but the shell does not honor the path change – RMorrisey Sep 17 '21 at 16:22
37

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

BiBi
  • 7,418
  • 5
  • 43
  • 69
  • 1
    Ok, but how to reload the environment so that bash saw the changes? – Alexander Apr 17 '20 at 13:54
  • 1
    @Alexander You'd use `. /root/.bashrc` to source the updated file in your existing bash session. By default when opening a new session that change should be caught otherwise. – erran Feb 02 '22 at 15:17
13

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

user2915097
  • 30,758
  • 6
  • 57
  • 59
12

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

Jianxin Gao
  • 2,717
  • 2
  • 19
  • 32
user859375
  • 3,529
  • 5
  • 21
  • 22
  • I think Jason Gao's answer should be the accepted one considering the question relates to Docker. Updating bash profiles is a fine way to store variables on a standard non-containerized environment but its cleaner to include an ENV step in your Dockerfile if you are deploying in a container. – NiallJG Mar 18 '17 at 06:52
  • 2
    The method for 'in environment' is incorrect according to this Ubuntu Document (Note: Variable expansion does not work in /etc/environment.). https://help.ubuntu.com/community/EnvironmentVariables#A.2Fetc.2Fenvironment – dangeroushobo Nov 01 '17 at 21:01
  • So setting the .bashrc file seems to only work when running as an interactive terminal, which makes sense as it would run the users default shell. Using that file will not work for running commands inside of the container unless you send them though bash. – Alex Barker Aug 30 '19 at 02:46
  • 1
    Someone please modify this. I've just wasted 1 hour banging my head against why it wouldn't expand. ty @dangeroushobo – MrR May 27 '21 at 20:17
7

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.

Tim
  • 1,585
  • 1
  • 18
  • 23
2

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}"
Eric Aya
  • 69,473
  • 35
  • 181
  • 253