Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

$PWD is not set in ENV instruction in a Dockerfile

I have a Dockerfile starts like this:

FROM ubuntu:16.04
WORKDIR /some/path
COPY . .
ENV PYTHONUSERBASE=$PWD/pyenv PATH=$PWD/pyenv/bin:$PATH
RUN echo "PWD is: $PWD"
RUN echo "PYENV is: $PYTHONUSERBASE"

I found $PWD (or ${PWD}) was not set when I run docker build, as a comparison, $PATH was correctly expanded.

Moreover, $PWD in RUN has no problem (It prints /some/path in this case)

So the output of the given Dockerfile would be:

PWD is: /some/path
PYENV is: /pyenv

Could somebody tell me why $PWD is so special? I guess it may be related to the behaviour of WORKDIR but I have no clue about that.

like image 385
cherrot Avatar asked Jun 09 '17 08:06

cherrot


People also ask

What is $PWD in Docker?

PWD is an environment variable that your shell will expand to your current working directory. So in this example, it would mount the current working directory, from where you are executing this command, to /usr/src/app inside your container.

Which Dockerfile instruction can you use to set an environment variable?

While you can't directly set ENV variable values when running docker build , you can use ARG to pass through --build-arg values right into your ENV instructions. You can change the value each time you run docker build without editing the Dockerfile.

What does ENV do in Dockerfile?

ENV is mainly meant to provide default values for your future environment variables. Running dockerized applications can access environment variables. It's a great way to pass configuration values to your project. ARG values are not available after the image is built.

Can Dockerfile have environment variables?

Dockerfile provides a dedicated variable type ENV to create an environment variable. We can access ENV values during the build, as well as once the container runs. Let's see how we can use it to pass value to our greetings script. There are two different ways to do it.


1 Answers

PWD is an special variable that is set inside a shell. When docker RUN something it does that with this form sh -c 'something', passing the pre-defined environment variables from ENV instructions, where PWD is not in that list (see it with docker inspect <image-id>).

ENV instructions does not launch a shell. Simply add or update the current list of env vars in the image metadata.

I would write your Dockerfile as this:

FROM ubuntu:16.04
ENV APP_PATH=/some/path
WORKDIR $APP_PATH
COPY . .
ENV PYTHONUSERBASE=$APP_PATH/pyenv PATH=$APP_PATH/pyenv/bin:$PATH
RUN echo "PWD is: $PWD"
RUN echo "PYENV is: $PYTHONUSERBASE"

Further info in docs:

The WORKDIR instruction sets the working directory for any RUN, CMD, ENTRYPOINT, COPY and ADD instructions that follow it in the Dockerfile. If the WORKDIR doesn’t exist, it will be created even if it’s not used in any subsequent Dockerfile instruction.

like image 119
Robert Avatar answered Oct 24 '22 10:10

Robert