1. Overview

In this article, we’ll see how to update the PATH variable in Docker. Firstly, we’ll update it globally. Then, we’ll restrict the change to a subset of instructions.

2. Updating the Global PATH Variable

The ENV statement can be used to update the PATH variable. Let’s write an example Dockerfile to showcase this behaviour:

FROM ubuntu:latest
RUN echo $PATH
ENV PATH="$PATH:/etc/profile"
RUN echo $PATH

The first line states that we use the most recent Ubuntu image. We’re also logging the value of the PATH variable before and after the ENV instruction.

Let’s build our image:

$ docker build -t baeldungimage .
#4 [1/3] FROM docker.io/library/ubuntu:latest
#5 [2/3] RUN echo /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
#5 0.683 /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
#6 [3/3] RUN echo /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/etc/profile
#6 0.893 /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/etc/profile

As expected, /etc/profile has been appended to PATH.

3. Updating PATH Only for a Sequence of Instructions

We’ll use a RUN instruction to run a sh script to export a new PATH. After that, we’ll add another instruction inside the same RUN statement. This will print the local value of PATH inside the RUN statement. We’ll also log the PATH global variable afterward to confirm that it didn’t change.

Here’s our new Dockerfile:

FROM ubuntu:latest
RUN echo $PATH
RUN export PATH="$PATH:/etc/profile"; echo $PATH
RUN echo $PATH

We can now build the image:

$ docker build -t baeldungimage . 
#7 [1/4] FROM docker.io/library/ubuntu:latest
#4 [2/4] RUN echo /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
#4 0.477 /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
#5 [3/4] RUN export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/etc/profile"; echo /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
#5 0.660 /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/etc/profile
#6 [4/4] RUN echo /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
#6 0.661 /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

The log confirms that after exporting the PATH variable, its value’s used by further instructions inside the same RUN command. However, the global variable hasn’t changed.

4. Updating PATH Inside Shell Sessions

Let’s now see how we can update PATH for shell sessions only. First, we’ll modify the .bashrc file to update the PATH at the beginning of every shell session. Then, we’ll start a shell session to check this behaviour.

4.1. Editing the .bashrc File

We’ll edit the .bashrc file to export a new PATH at the beginning of every shell session. To do so, we’ll run a quick script to append the export to the original file. As we did earlier, we’ll check that this change doesn’t impact the global PATH variable.

Here’s the new Dockerfile:

FROM ubuntu:latest
RUN echo $PATH
RUN echo "export PATH=$PATH:/etc/profile" >> ~/.bashrc
RUN cat ~/.bashrc
RUN echo $PATH

Additionally, let’s note that we used the cat command to view the file.

Let’s build the image:

$ docker build -t baeldungimage . 
#4 [1/5] FROM docker.io/library/ubuntu:latest
#5 [2/5] RUN echo /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
#5 0.447 /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
#6 [3/5] RUN echo "export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/etc/profile" >> ~/.bashrc
#7 [4/5] RUN cat ~/.bashrc
#7 0.956 # ~/.bashrc: executed by bash(1) for non-login shells.
#7 0.956 # see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
#7 0.956 # for examples
#7 0.956
#7 0.956 # If not running interactively, don't do anything
#7 0.956 [ -z "$PS1" ] && return
[... .bashrc full content]
#7 0.956 export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/etc/profile
#7 DONE 1.0s
#8 [5/5] RUN echo /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
#8 0.867 /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

As we can see, the global PATH didn’t change. However, the export line was indeed added at the end of the file. As a result, whenever .bashrc is loaded, it updates the PATH variable for the running shell.

4.2. Running a Container in Interactive Mode

Let’s now focus on the few first lines of the .bashrc file from the output we saw earlier. These lines are from the original file. It states clearly “If not running interactively, don’t do anything”.

It’s crucial to understand that when we build a Dockerfile, the RUN command’s not interactive. So we won’t be able to just source our .bashrc file and RUN a script during the build to check if the path has been updated.

Instead, we can run a container in interactive mode and open a shell session:

$ docker run -it --name interactiveimage baeldungimage
root@18781222594f:/# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/etc/profile

Once in the shell session, we printed the PATH. We can see that /etc/profile was appended, confirming that our .bashrc file has been taken into account.

5. Conclusion

In this tutorial, we’ve seen how to update the PATH variable in Docker. Initially, we updated the variable globally, but we’ve also learned how to update it with more restrictions.

As always, the code is available over on GitHub.

Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.