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

时间:2016-09-20 15:20:40

标签: docker dockerfile

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

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不存在

2 个答案:

答案 0 :(得分:50)

ARG用于设置docker build过程中使用的环境变量 - 它们不会出现在最终图像中,这就是您在使用{{{{{{{{ 1}}。

您使用docker run进行仅在构建图像时相关的设置,并且您从图像运行的容器不需要这些设置。您可以在构建期间和容器中使用ARG来获取环境变量。

使用此Dockerfile:

ENV

您可以像使用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 .

答案 1 :(得分:8)

我将总结this精彩文章中的要点。


ARG与ENV

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

ENV 值可用于容器,但在Docker构建期间(从引入它们的行开始)也可使用RUN样式的命令。 如果您使用bash(RUN export VARI = 5 &&…)在中间容器中设置环境变量,则该变量将不会保留在下一个命令中。

2)更长的解释:
ARG 也称为生成时变量。它们只有在使用ARG指令在Dockerfile中“宣布”之时才可用,直到构建映像为止。正在运行的容器无法访问ARG变量的值。这也适用于CMD和ENTRYPOINT指令,它们仅告诉容器默认情况下应运行的内容。如果您告诉Dockerfile期望使用各种ARG变量(没有默认值),但是在运行build命令时未提供任何变量,则会出现错误消息。

但是,在构建映像后,可以通过查看映像的docker历史记录轻松检查ARG值。因此,对于敏感数据,它们是一个糟糕的选择。

在向您介绍ENV指令后,

ENV 变量在构建过程中也可用。但是,与ARG不同,从最终映像开始的容器也可以访问它们。启动容器时,可以覆盖ENV值,详情请参见下文。

3)带diagrem:
这是围绕从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映像时,可以使用ARG设置–build-arg值:

$ docker build --build-arg some_variable_name=a_value

使用上面的Dockerfile运行该命令将导致打印以下行(以及其他内容):哦,瞧瞧那个a_value

那么,这如何转换为使用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

当您尝试设置ARG中未提及的Dockerfile变量时,Docker会抱怨。

设置ENV值

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

构建图像时,如上所述,您只能提供ARG值。您无法直接为ENV变量提供值。但是,ARGENV可以一起工作。您可以使用ARG设置ENV vars的默认值。
这是基本的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的摘要,使用动态的内置环境值:

# 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文件。
所有这些都将覆盖ENV中的所有默认Dockerfile值。
ARG不同,您可以将各种环境变量传递到容器。甚至没有在Dockerfile中明确定义的那些。
是否执行任何操作取决于您的应用程序。

选项1:逐一提供值
在命令行中,使用-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

选项2:从主机传递环境变量值
与上述方法相同。
唯一的区别是,您不提供值,而只是命名变量。这将使Docker访问主机环境中的当前值并将其传递给容器。

$ docker run -e env_var_name alpine env

对于docker-compose.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的常用方法

这是一个简短的备忘单,它结合了ARGENV的可用性概述以及从命令行设置它们的常用方法。

enter image description here