Dockerfile的ENV

蓝黑2020 2024-06-17 17:07:03 阅读 50

文章目录

环境总结测试测试1测试2测试3测试4测试5测试6 参考

环境

RHEL 9.3Docker Community 24.0.7

总结

如果懒得看测试的详细信息,可以直接看结果:

一条 ENV 指令可以定义多个环境变量Dockerfile里可以包含多条 ENV 指令。环境变量的值不需要用双引号引起来,如果用了双引号,也会自动被去掉。环境变量的值如果包含空格,可以用双引号引起来,或者用 \ 将其转义。环境变量的值如果包含双引号,可以用 \ 将其转义。ENV 指令里可以引用之前的 ENV 指令里定义的环境变量。在同一条 ENV 指令里,无法互相引用: 如果是本条指令里新定义的变量,则当作没有定义。如果是之前指令里定义过,本条指令里有修改的变量,则获取的仍然是之前指令里的值。 在启动容器时,可以通过 --env 选项覆盖Dockerfile里设置的环境变量。stage会继承其parent image的环境变量。如果只是构建期的变量,不要用 ENV 指令,否则会影响image使用。如果想要unset变量,需要把set和unset放到同一个 RUN 指令里。

测试

测试1

创建 Dockerfile 文件如下:

FROM alpineENV VAR1=value1 VAR2="value2" VAR3="hello world" \ VAR4=hello\ world ENV VAR5="He said: \"It's good!\""

构建:

docker build -t kai0108_1 .

启动容器,查看环境变量

➜ ~ docker run kai0108_1 envVAR1=value1VAR2=value2VAR3=hello worldVAR4=hello worldVAR5=He said: "It's good!"

注:只列出了相关的环境变量。

总结:

一条 ENV 指令可以定义多个环境变量。Dockerfile里可以包含多条 ENV 指令。环境变量的值不需要用双引号引起来,如果用了双引号,也会自动被去掉。环境变量的值如果包含空格,可以用双引号引起来,或者用 \ 将其转义。环境变量的值如果包含双引号,可以用 \ 将其转义。

测试2

创建 Dockerfile 文件如下:

FROM alpineENV VAR1=value1 VAR2=aaa${ VAR1}bbbENV VAR3=ccc${ VAR1}dddENV VAR4=value4ENV VAR5=aaa${ VAR4}bbb VAR6=ccc${ VAR5}dddENV VAR7=value7ENV VAR7=value8 VAR8=aaa${ VAR7}bbb

启动容器,查看环境变量:

➜ ~ docker run kai0108_2 envVAR1=value1VAR2=aaabbbVAR3=cccvalue1dddVAR4=value4VAR5=aaavalue4bbbVAR6=cccdddVAR7=value8VAR8=aaavalue7bbb

总结:

ENV 指令里可以引用之前的 ENV 指令里定义的环境变量。在同一条 ENV 指令里,无法互相引用: 如果是本条指令里新定义的变量,则当作没有定义。如果是之前指令里定义过,本条指令里有修改的变量,则获取的仍然是之前指令里的值。

测试3

创建 Dockerfile 文件如下:

FROM alpineENV VAR1=value1

启动容器,设置环境变量 VAR1

➜ ~ docker run --env VAR1=hello kai0108_3 envVAR1=hello

总结:

在启动容器时,可以通过 --env 选项覆盖Dockerfile里设置的环境变量。

测试4

创建 Dockerfile 文件如下:

FROM alpine AS baseENV VAR1=value1FROM baseENV VAR2=aaa${ VAR1}bbb

启动容器,查看环境变量:

➜ ~ docker run kai0108_4 envVAR1=value1VAR2=aaavalue1bbb

总结:

stage会继承其parent image的环境变量。

测试5

创建 Dockerfile 文件如下:

FROM ubuntu:trustyENV DEBIAN_FRONTEND=noninteractiveRUN apt-get update && apt-get install -y curl

注: DEBIAN_FRONTEND=noninteractive 表示在 apt-get install 安装的过程中,使用缺省设置,不与用户交互(比如弹出对话框),当然如果不加 -y 选项,还是会让用户确认安装的。在构建时,无法与用户交互,所以要设置该环境变量(本例中安装 curl 其实并不会弹出对话框,只是个示例)。

构建:

docker build -t kai0108_5 .

注:构建会非常慢,因为要连接国外的网站。

启动容器,并进入容器:

docker run -it kai0108_5

安装 mail-stack-delivery

apt-get -y install mail-stack-delivery

注:这里安装 mail-stack-delivery ,只是为了测试安装过程中是否会弹出对话框。

在安装过程中,本来应该会弹出如下对话框:

在这里插入图片描述

但是实际上并没有弹出对话框。

原因很简单,因为有环境变量 DEBIAN_FRONTEND=noninteractive

本来,设置该环境变量只是为了在构建image时不与用户交互,但是在image里也保留了该环境变量,以至于影响了 apt-get install 的行为,这可能会对用户造成困扰。

解决办法有两种:

方法1:在 RUN 指令里设置环境变量,只对本指令有效:

RUN DEBIAN_FRONTEND=noninteractive apt-get update && apt-get install -y curl 方法2:通过 ARG 指令设置变量,只在构建期有效:

ARG DEBIAN_FRONTEND=noninteractiveRUN apt-get update && apt-get install -y curl

总结:

如果只是构建期的变量,不要用 ENV 指令,否则会影响image使用。

测试6

创建 Dockerfile 文件如下:

FROM alpineENV VAR1=value1RUN echo aaa${ VAR1}bbb > /tmp/a.txtRUN unset VAR1RUN echo ccc${ VAR1}ddd > /tmp/b.txt

构建:

docker build -t kai0108_6 .

启动容器,并进入容器查看:

➜ ~ docker run -it kai0108_6/ # cat /tmp/a.txtaaavalue1bbb/ # cat /tmp/b.txtcccvalue1ddd/ # envVAR1=value1......

可见,unset变量并不起作用。这是因为 ENV 指令会创建一个layer。

若想要unset变量,需要把set和unset放到同一个layer里,也就是同一个 RUN 指令里。

创建 Dockerfile 文件如下:

FROM alpineRUN export VAR1=value1 \ && echo aaa${ VAR1}bbb > /tmp/a.txt \ && unset VAR1 \ && echo ccc${ VAR1}ddd > /tmp/b.txtRUN echo eee${ VAR1}fff > /tmp/c.txt

构建:

docker build -t kai0108_7 .

启动容器,并进入容器查看:

➜ ~ docker run -it kai0108_7/ # cat /tmp/a.txtaaavalue1bbb/ # cat /tmp/b.txtcccddd/ # cat /tmp/c.txteeefff/ # envHOSTNAME=13dcd240cd01SHLVL=1HOME=/rootTERM=xtermPATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binPWD=/

可见,这次达到了预期的目的。

总结:

如果想要unset变量,需要把set和unset放到同一个 RUN 指令里。

参考

https://docs.docker.com/engine/reference/builder/#envhttps://docs.docker.com/develop/develop-images/instructions/#env


声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。