通过'——build-arg '传递覆盖Dockerfile中的环境变量



我正在构建两个docker映像,一个是基本docker映像,另一个是自定义映像。

自定义映像是从基本映像构建的,但我想在映像中分配不同的环境变量。

例如,我为这两个映像准备了以下Dockerfiles:

For base image:

# base.Dockerfile
FROM ubuntu
ARG MY_ENV
ENV MY_ENV=${MY_ENV}
# RUNs to install basic tools
# ...

自定义图像

# 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
# ...

然后按如下方式构建并运行。

# 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' .

我预料到我期望'my_value_in_custom'my_custom_image中存储在MY_ENV中,但'my_value_in_base'被存储。

$ 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

当我构建自定义映像时,我如何覆盖MY_ENV?

docker run -e MY_ENV='my_value_in_custom'改变了容器中的环境变量,但这不是我要找的,因为我想改变自定义图像中的环境变量。

我怀疑不可能以您建议的特定方式替换环境变量。

DockerfileARG的文档说明:

使用ENV指令定义的环境变量总是覆盖同名的ARG指令。

你可能就是这种情况。在第二个Dockerfile中,定义了一个环境变量$MY_ENV(来自基本映像),因此即使在这个Dockerfile中有一个ARG,在它之前没有ENV,现有的环境变量仍然优先。

在实践中,你可能根本不需要在Dockerfile中设置这些变量。您还可以在运行容器时指定环境变量值,这是指定许多值(相关的主机名、凭据)的更合适的方法。在你的问题末尾的' docker run -e'调用就是这样做的,对于用户提供的设置,我经常希望这是正确的。

如果您确实需要覆盖派生映像中的环境变量,并且该值确实需要在构建时可配置,那么您需要为ARG指定一个不同的名称。

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' .

最新更新