Updating PATH environment variable permanently in Docker container
Environment VariablesDockerLinux ContainersEnvironment Variables Problem Overview
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.
Environment Variables Solutions
Solution 1 - Environment Variables
If you want to include a /new/path
in the Dockerfile, adding the line:
ENV PATH "$PATH:/new/path"
in Dockerfile should work.
Solution 2 - Environment Variables
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
Solution 3 - Environment Variables
Put in your Dockerfile a line ENV PATH xxx
see an example in this Dockerfile https://gist.github.com/deepak/5933685
Solution 4 - Environment Variables
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
Solution 5 - Environment Variables
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}"
Solution 6 - Environment Variables
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 byENV
will be taken andbashrc
scripts will not run. docker run -it <image> /bin/bash
invokes an interactive shell.bashrc
will be run and could override anything set inENV
, if the for instancePATH
is not defined in the usualPATH=$PATH:/...
syntax in any of thebashrc
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.