Home > Software design >  Overwriting of environment variables in Dockerfile with passed by `--build-arg`
Overwriting of environment variables in Dockerfile with passed by `--build-arg`

Time:12-02

I am building two docker images, one is a base docker image, and another is a custom image.

The custom image is build from base image, but I want to assign different environment variables in the image.

For example, I prepare following Dockerfiles for these two images.

For base image:

# base.Dockerfile
FROM ubuntu
ARG MY_ENV
ENV MY_ENV=${MY_ENV}

# RUNs to install basic tools
# ...

For custom image

# base.Dockerfile
FROM my_base_image
ARG MY_ENV
ENV MY_ENV=${MY_ENV}
ENV IMAGE='This container is from a custom image'
# RUNs to setup custom images
# ...

Then build and run like follows.

# build a base image
docker build --file 'base.Dockerfile' \
  --build-arg MY_ENV='my_value_in_base' \
  --tag 'my_base_image' . 

# build a custom image
docker build --file 'custom.Dockerfile' \
  --build-arg MY_ENV='my_value_in_custom' \
  --tag 'my_custom_image' .

I expected that in I expected that 'my_value_in_custom' is stored in MY_ENV in my_custom_image, but 'my_value_in_base' is stored.

$ docker run  my_custom_image env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=9fd195c99739
MY_ENV=my_value_in_base
IMAGE=This container is from custom image
HOME=/root

How can I overwrite MY_ENV when I build the custom image?

docker run -e MY_ENV='my_value_in_custom' changes the environment variables in the container, but this is not what I am looking for as I want to change the environment variables in the custom image.

CodePudding user response:

I suspect it's not possible to replace environment variables in the specific way you suggest.

The documentation on Dockerfile ARG notes:

Environment variables defined using the ENV instruction always override an ARG instruction of the same name.

You're probably in this case. In the second Dockerfile, an environment variable $MY_ENV is defined (from the base image), and so even though there's an ARG without an ENV before it in this Dockerfile, the extant environment variable still takes precedence.

In practice you may not need to set this variables in a Dockerfile at all. You can also specify environment variable values when you run a container, and this is a more appropriate way to specify many values (related host names, credentials). The `docker run -e' invocation at the end of your question does this, and for a user-provided setting, I'd frequently expect that to be correct.

If you really need to override the environment variable in the derived image, and the value really needs to be build-time configurable, then you need to give the ARG a different name.

FROM my_base_image
ARG CUSTOM_MY_ENV
ENV MY_ENV=${CUSTOM_MY_ENV}
docker build --file 'custom.Dockerfile' \
  --build-arg CUSTOM_MY_ENV='my_value_in_custom' \
  --tag 'my_custom_image' .
  • Related