Docker经典面试题:Dockerfile中为啥不通过export设置环境变量

我们日常写Dockerfile的时候,如果想设置环境变量可以通过ENV指令,格式:

ENV = =...

但很少有童鞋注意到,为啥我们不能通过常规的RUN export 直接设置环境变量呢,为啥还需要引入一个ENV的指令,难道不是多此一举吗?很多看似简单的东西,如果不深入原理,很容易停留在现象的表层。

Docker经典面试题:Dockerfile中为啥不通过export设置环境变量

答案当然不是,通过RUN的方式在构建镜像的过程中,每次RUN都会生成一个中间层,这个中间层是RUN命令执行的上下文。但如果通过RUN export一个环境变量,在这RUN进程的上下文中是可以生效的,但伴随着这一层RUN命令的结束,这个环境变量的周期也随之结束,并没有持久化到镜像里面。下面通过两个案例说明一下:

案例一

我们先在终端一中启动一个容器,并设置一个TEST环境变量

# docker run -it busybox sh
# export TEST=test

登录到终端二中,进入容器查看环境变量

# docker exec -it 9c18a594aa09(终端一创建容器ID) sh
# env

输出的结果中并没有终端一里面设置的环境变量TEST。这个实验在本质上与Docker并无关系,而是Linux系统本来就是这样设计的,通过export设置的环境变量,只是在当前程序的上下文有效,当通过exec进入容器后,启动一个新进程,所以无法读取这个环境变量。

案例二

创建一个测试的Dockerfile文件,分别使用ENV和RUN export的方式设置环境变量。

FROM busybox
ENV FOO=foo
RUN export BAR=bar
RUN export BAZ=baz && echo “$FOO $BAR $BAZ“

执行构建命令docker build后将会输出下面的结果

# docker build -t testenv .
Sending build context to Docker daemon 2.048 kB
Step 1/4 : FROM busybox
 ---> d8233ab899d4
Step 2/4 : ENV FOO foo
 ---> Running in 51ddaa260ea7
 ---> f8a1656d3e7e
Removing intermediate container 51ddaa260ea7
Step 3/4 : RUN export BAR=bar
 ---> Running in 803d486a476a
 ---> 5f12d131af2a
Removing intermediate container 803d486a476a
Step 4/4 : RUN export BAZ=baz && echo “$FOO $BAR $BAZ“
 ---> Running in a9a6dd63eb90
foo  baz
 ---> 0ad9d79ebc6c
Removing intermediate container a9a6dd63eb90
Successfully built 0ad9d79ebc6c

从输出的结果可以看到通过export设置的环境变量只能在当前进程的上下文有效,而无法持久化到镜像中。而通过ENV设置的环境变量将保存到镜像文件的config.json的文件中,从而可以持续有效。

展开阅读全文

页面更新:2024-03-28

标签:环境变量   都会   中间层   上下文   终端   表层   指令   容器   持久   进程   命令   案例   结束   方式   文件   经典   科技

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号

Top