如何在构建 docker 期间设置环境变量

我试图在构建期间在docker容器中设置环境变量,但没有成功。在使用运行命令时设置它们,但我需要在构建期间设置它们。

Dockerfile

FROM ubuntu:latest
ARG TEST_ENV=something

我用来构建的命令

docker build -t --build-arg TEST_ENV="test" myimage .

运行

docker run -dit myimage

我正在检查可用的环境变量使用

docker exec containerid printenv

结果是

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=e49c1abfd58b
TERM=xterm
no_proxy=*.local, 169.254/16
HOME=/root

TEST_ENV不存在

254912 次浏览

ARG用于设置在docker build过程中使用的环境变量——它们不会出现在最终的图像中,这就是为什么当你使用docker run时看不到它们。

你可以使用ARG来设置那些只在构建映像时相关的设置,而你从映像中运行的容器并不需要这些设置。你可以使用ENV作为构建期间和容器中使用的环境变量。

使用这个Dockerfile:

FROM ubuntu
ARG BUILD_TIME=abc
ENV RUN_TIME=123
RUN touch /env.txt
RUN printenv > /env.txt

你可以像使用docker build -t temp --build-arg BUILD_TIME=def .一样重写构建参数。然后你就会得到你想要的:

> docker run temp cat /env.txt
HOSTNAME=b18b9cafe0e0
RUN_TIME=123
HOME=/root
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
BUILD_TIME=def
PWD=/

我将从伟大的文章总结重点。


ARG Vs ENV

< >强1)简短说明: < br > ARG仅在构建Docker映像期间可用(RUN等),而不是在映像创建并从映像启动容器之后(ENTRYPOINT, CMD)。

ENV值可用于容器,但在Docker构建期间也可用于run样式的命令,从引入它们的行开始。 如果使用bash在中间容器中设置环境变量(RUN export VARI=5 &&

.…)它将不会在下一个命令中持续存在

< >强2)较长的解释: < br > ARG也称为构建时变量。它们只在Dockerfile中使用ARG指令“宣布”的那一刻起可用,直到映像被构建的那一刻。运行中的容器不能访问ARG变量的值。这也适用于CMD和ENTRYPOINT指令,它们只是告诉容器在默认情况下应该运行什么。如果你告诉Dockerfile期望各种ARG变量(没有默认值),但在运行build命令时没有提供,将会有一个错误消息。

然而,通过查看映像的docker历史,可以很容易地在映像构建后检查ARG值。因此,对于敏感数据,它们是一个糟糕的选择。

ENV变量在构建过程中也可用,只要你用ENV指令引入它们。然而,与ARG不同的是,它们也可以被从最终图像开始的容器访问。ENV值可以在启动容器时被覆盖,下面将详细介绍。

< >强3)有分歧: < br > 下面是一个关于从Dockerfile构建Docker镜像和运行容器的过程中ARG和ENV可用性的简化概述

它们是重叠的,但是ARG在容器内部是不可用的。

enter image description here

设置ARG和ENV值

设置ARG值

所以,你有你的Dockerfile,它定义了ARGENV值。如何设置,在哪里设置?你可以在Dockerfile中保留它们为空,或者设置默认值。如果你没有为没有默认值的预期ARG变量提供一个值,你会得到一个错误消息。

下面是一个Dockerfile的例子,包括默认值和不包含默认值:

ARG some_variable_name
# or with a hard-coded default:
#ARG some_variable_name=default_value


RUN echo "Oh dang look at that $some_variable_name"
# you could also use braces - ${some_variable_name}

当从命令行构建Docker映像时,你可以使用–build-arg设置ARG值:

$ docker build --build-arg some_variable_name=a_value

使用上面的Dockerfile运行该命令,将导致打印以下行(以及其他行)

那么,这是如何转换为使用docker-compose.yml文件?< br > 使用docker-compose时,你可以在args块中为ARG指定要传递的值:
(docker-compose。yml文件)< / p >
version: '3'


services:
somename:
build:
context: ./app
dockerfile: Dockerfile
args:
some_variable_name: a_value

当你试图设置一个不是Dockerfile中提到的ARG的变量时,Docker会报错。

设置ENV值

那么,如何设置ENV值呢?你可以在启动容器时这样做(我们将在下面稍微介绍一下),但是你也可以通过硬编码直接在你的Dockerfile中提供默认的ENV值。此外,您还可以为环境变量设置动态默认值!

当构建一个映像时,你唯一能提供的是ARG值,如上所述。不能直接为ENV变量提供值。然而,ARGENV都可以一起工作。你可以使用ARG来设置ENV vars的默认值。< br > 下面是一个基本的Dockerfile,使用硬编码的默认值:

# no default value
ENV hey
# a default value
ENV foo /bar
# or ENV foo=/bar


# ENV values can be used during the build
ADD . $foo
# or ADD . ${foo}
# translates to: ADD . /bar

下面是Dockerfile的代码片段,使用动态构建时的env值:

# expect a build-time variable
ARG A_VARIABLE
# use the value to set the ENV var default
ENV an_env_var=$A_VARIABLE
# if not overridden, that value of an_env_var will be available to your containers!
一旦构建了映像,就可以启动容器并以三种不同的方式为ENV变量提供值,要么通过命令行,要么使用docker-compose.yml文件。< br > 所有这些都将覆盖Dockerfile. conf中任何默认的ENV值。与ARG不同,你可以将各种环境变量传递给容器。即使是在Dockerfile中没有显式定义的。< br > 这取决于你的应用程序是否会做任何事情 < p > 选项1:逐个提供值 < br > 在命令行中,使用-e标志:

$ docker run -e "env_var_name=another_value" alpine env

docker-compose.yml文件:

version: '3'


services:
plex:
image: linuxserver/plex
environment:
- env_var_name=another_value
< p > 选项2:从主机传递环境变量值 < br > 这与上面的方法相同。< br > 唯一的区别是,您不提供值,而只是命名变量。这将使Docker访问主机环境中的当前值并将其传递给容器
$ docker run -e env_var_name alpine env

对于docker-compose.yml文件,为了达到同样的效果,省略等式符号及其后面的所有内容。

version: '3'


services:
plex:
image: linuxserver/plex
environment:
- env_var_name
< p > 选项3:从文件中获取值(env_file) < br > 我们可以指定一个要从中读取值的文件,而不是将变量写出来或硬编码(根据12因素的人来说不是很有品味)。这样一个文件的内容看起来像这样:

env_var_name=another_value
上面的文件被称为env_file_name(名称任意),它位于当前目录。< br > 您可以引用文件名,文件名将被解析以提取要设置的环境变量:

$ docker run --env-file=env_file_name alpine env

对于docker-compose.yml文件,我们只引用一个env_file, Docker解析它以设置变量。

version: '3'


services:
plex:
image: linuxserver/plex
env_file: env_file_name

从命令行设置ARG和ENV的常用方法

下面是一个小备考单,结合了ARGENV可用性的概述,以及从命令行设置它们的常用方法。

enter image description here