Reputation: 3944
I have a simple Dockerfile that looks like this:
FROM alpine:3
RUN echo "$HOME" # Prints '/root'
ENV OTHER_HOME="$HOME"
RUN echo "$OTHER_HOME" # Prints nothing!
RUN echo "$PATH" # Prints '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
ENV OTHER_PATH="$PATH"
RUN echo "$OTHER_PATH" # Prints '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
Which I build like this:
docker build . --no-cache
The output is perplexing. $OTHER_PATH
prints as expected, but $OTHER_HOME
is blank. Can anyone explain this behavior?
% docker build . --no-cache
Sending build context to Docker daemon 335.4kB
Step 1/7 : FROM alpine:3 AS build-stage
---> e7d92cdc71fe
Step 2/7 : RUN echo "$HOME"
---> Running in f9cd2769cd78
/root
Removing intermediate container f9cd2769cd78
---> d13f007a1fdf
Step 3/7 : ENV OTHER_HOME="$HOME"
---> Running in 7493ca43f9f3
Removing intermediate container 7493ca43f9f3
---> 2d6acfe45228
Step 4/7 : RUN echo "$OTHER_HOME"
---> Running in fb960138f43e
Removing intermediate container fb960138f43e
---> caa9719aeee5
Step 5/7 : RUN echo "$PATH"
---> Running in fe1eacf50d30
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Removing intermediate container fe1eacf50d30
---> 17267879b82e
Step 6/7 : ENV OTHER_PATH="$PATH"
---> Running in 9dd894199ea4
Removing intermediate container 9dd894199ea4
---> fa43f399604f
Step 7/7 : RUN echo "$OTHER_PATH"
---> Running in 89d67d8b6cfe
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Removing intermediate container 89d67d8b6cfe
---> 440133fc0052
Successfully built 440133fc0052
UPDATE: Stranger still, if I manually assign $HOME
, the value is usable later!
FROM alpine:3
ENV HOME='/root'
RUN echo "$HOME"
ENV OTHER_HOME="$HOME"
RUN echo "$OTHER_HOME"
This Dockerfile results in:
% docker build . --no-cache
Sending build context to Docker daemon 335.4kB
Step 1/8 : FROM alpine:3 AS build-stage
---> e7d92cdc71fe
Step 2/8 : ENV HOME='/root'
---> Running in 4cb8a8e45b18
Removing intermediate container 4cb8a8e45b18
---> 40d0156fe68b
Step 3/8 : RUN echo "$HOME"
---> Running in 051cf7d138fb
/root
Removing intermediate container 051cf7d138fb
---> dc34c6859bcd
Step 4/8 : ENV OTHER_HOME="$HOME"
---> Running in 01dcc2788761
Removing intermediate container 01dcc2788761
---> 540ca4e9225a
Step 5/8 : RUN echo "$OTHER_HOME"
---> Running in 4e0d31d1f847
/root
Upvotes: 7
Views: 2760
Reputation: 264701
The $HOME
variable is set when the container is spawned by the RUN steps. Since it is not defined to docker in any of the previous ENV or ARG steps, you cannot use this variable in a new ENV step. You can see the list of variables defined for docker by inspecting the base image:
$ docker image inspect alpine:3 --format '{{json .Config.Env}}' | jq .
[
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
]
In this case, the only variable is PATH
. If you run a build, you'll see other variables getting defined, some by the shell when you use the string syntax, and others by docker/the OS when the exec syntax is used:
$ cat df.env
FROM alpine:3
RUN [ "env" ]
RUN env
$ DOCKER_BUILDKIT=0 docker build -t test-env -f df.env .
Sending build context to Docker daemon 25.09kB
Step 1/3 : FROM alpine:3
---> a187dde48cd2
Step 2/3 : RUN [ "env" ]
---> Running in 96b16e35b986
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=96b16e35b986
HOME=/root
Removing intermediate container 96b16e35b986
---> b11077eeb243
Step 3/3 : RUN env
---> Running in 90237b5b485f
HOSTNAME=90237b5b485f
SHLVL=1
HOME=/root
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/
Removing intermediate container 90237b5b485f
---> 2b3715def1df
Successfully built 2b3715def1df
Successfully tagged test-env:latest
In this case, HOME
and HOSTNAME
get defined when you run an exec, and SHLVL
and PWD
are added to that when you use a shell (/bin/sh
).
Upvotes: 8
Reputation: 869
You can only workaround the issue as this is a reported bug on GitHub:
https://github.com/moby/moby/issues/28971
Therefore, there is no 'real' answer to your question.
Upvotes: 3