Cameron Hudson
Cameron Hudson

Reputation: 3944

Dockerfile: $HOME is set, but becomes blank when using it to define other environment variables

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

Answers (2)

BMitch
BMitch

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

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

Related Questions