Dockerfile: reference previously defined ENV in another ENV

Viewed 758

I have a Dockerfile in which I set some environment variables (for use when I run the container). Some of the environment variables depend on previous environment variables. I want to be DRY and avoid having to hard-code the value of environment variables multiple times, when I could substitute in a variable.

In this simple example, the PYTHONPATH environment variable uses values from the PROJ_DIR environment variable.

FROM python:3.8.4

ENV PROJ_DIR=/myproj/ \
    PYTHONPATH=${PROJ_DIR}:${PYTHONPATH}

However, when I actually run the container, the PROJ_DIR correctly gets set, but the dependent variable, PYTHONPATH, does not get set.

docker build -f Dockerfile . -t test-docker
docker run --rm -it test-docker:latest bash 
root@60fc899899a1:/# export | grep -i proj
declare -x PROJ_DIR="/myproj/"
root@60fc899899a1:/# export | grep -i pythonpath
declare -x PYTHONPATH=":"

How do I use previously set environment variables in a Dockerfile?

2 Answers

For this to work you would need to spearate out the variables and use multiline assignment.

ENV PROJ_DIR /myproj/
ENV PYTHONPATH ${PROJ_DIR}:${PYTHONPATH}

Throughout the entire instruction, environment variable substitution will use the same value for each variable. In your case PROJ_DIR is yet to be assigned a value, so it returns empty in PYTHONPATH varaible.

To be more clear, in:

ENV x=hello
ENV x=world z=$x

z will have value hello and not world.

Due to multiline there will be not be any additonal layers getting created as ENV layers do get squashed.

Hope that helps.

You can reuse environment variables that were previously set outside but not inside an ENV, since all statements in the same ENV pick up the value defined before the ENV is processed. So you should split it into separate ENVs.

ENV PROJ_DIR=/myproj/
ENV PYTHONPATH=${PROJ_DIR}:${PYTHONPATH}
Related