我将总结这篇伟大文章中的亮点。
ARG VS 环境
1)简短说明:
ARG只在构建Docker映像期间可用(RUN等),而不是在映像创建并从映像启动容器之后(ENTRYPOINT, CMD)。
容器可以使用ENV值,但在Docker构建过程中,从引入ENV值的行开始,也可以使用run样式的命令。
如果您使用bash在中间容器中设置了一个环境变量(RUN export VARI=5 &&…),它将不会在下一个命令中保持。
2 ) Longer explanation:
ARG are also known as build-time variables. They are only available from the moment they are ‘announced’ in the Dockerfile with an ARG instruction up to the moment when the image is built. Running containers can’t access values of ARG variables. This also applies to CMD and ENTRYPOINT instructions which just tell what the container should run by default. If you tell a Dockerfile to expect various ARG variables (without a default value) but none are provided when running the build command, there will be an error message.
然而,通过查看映像的docker历史,可以很容易地在映像构建后检查ARG值。因此,对于敏感数据,它们是一个糟糕的选择。
在构建过程中也可以使用ENV变量,只要您使用ENV指令引入它们即可。然而,与ARG不同的是,它们也可以被从最终图像开始的容器访问。ENV值可以在启动容器时被覆盖,下面将详细介绍。
3)有分歧:
下面是一个关于从Dockerfile构建Docker映像和运行容器的过程的ARG和ENV可用性的简化概述。
它们是重叠的,但是ARG在容器内部是不可用的。
设置ARG和ENV值
设置ARG值
你有Dockerfile,它定义了ARG和ENV值。如何设置,在哪里设置?你可以在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文件?
当使用docker-compose时,你可以在args块中指定要传递给ARG的值:
(docker-compose。yml文件)
version: '3'
services:
somename:
build:
context: ./app
dockerfile: Dockerfile
args:
some_variable_name: a_value
当你试图设置一个不是Dockerfile中提到的ARG的变量时,Docker会报错。
设置ENV值
那么,如何设置ENV值呢?你可以在启动容器时这样做(我们将在下面稍微介绍一下),但是你也可以通过硬编码直接在Dockerfile中提供默认的ENV值。此外,您还可以为环境变量设置动态默认值!
在构建映像时,你唯一能提供的是ARG值,如上所述。您不能直接为ENV变量提供值。然而,ARG和ENV都可以协同工作。您可以使用ARG来设置ENV变量的默认值。
下面是一个基本的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的代码片段,使用动态的on-build 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文件。
所有这些都将覆盖Dockerfile中的任何默认ENV值。与ARG不同,您可以将各种环境变量传递给容器。即使是Dockerfile中没有明确定义的。
这取决于你的应用程序是否会做任何事情。
选项1:逐个提供值
在命令行中,使用-e标志:
$ docker run -e "env_var_name=another_value" alpine env
从码头编曲。yml文件:
version: '3'
services:
plex:
image: linuxserver/plex
environment:
- env_var_name=another_value
选项2:从主机传递环境变量值
这与上面的方法相同。
唯一的区别是,您不提供值,而只是命名变量。这将使Docker访问主机环境中的当前值并将其传递给容器。
$ docker run -e env_var_name alpine env
对于码头编曲。Yml文件,为了达到同样的效果,省略方程符号和后面的所有内容。
version: '3'
services:
plex:
image: linuxserver/plex
environment:
- env_var_name
选项3:从文件中获取值(env_file)
我们可以指定一个要从中读取值的文件,而不是将变量写出来或硬编码(根据12因素的人来说不是很有品味)。这样一个文件的内容看起来像这样:
env_var_name=another_value
上面的文件称为env_file_name(名称任意),它位于当前目录中。
你可以引用文件名,它会被解析以提取要设置的环境变量:
$ 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的常用方法
下面是一个小备备单,结合了ARG和ENV可用性的概述,以及从命令行设置它们的常用方法。