如何在运行docker容器时覆盖环境变量

如何在运行docker容器时覆盖环境变量,docker,Docker,我试图理解在运行的docker容器中覆盖环境变量的方法 我在其他SO帖子中尝试了以下选项。每次我通过docker exec-e设置环境变量时,它都会将环境变量显示为已设置。在下一次跑步时,它消失了 启动docker的命令: docker run -itd --rm -e VAR1=test_var1 -e VAR2=test_var2 --name "test" phusion/baseimage:18.04-1.0.0 运行docker exec以设置环境变量 clou

我试图理解在运行的docker容器中覆盖环境变量的方法

我在其他SO帖子中尝试了以下选项。每次我通过
docker exec-e
设置环境变量时,它都会将环境变量显示为已设置。在下一次跑步时,它消失了

启动docker的命令:

docker run -itd --rm -e VAR1=test_var1 -e VAR2=test_var2  --name "test" phusion/baseimage:18.04-1.0.0
运行docker exec以设置环境变量

cloud_user@vijaygharge1c:/var/lib/docker$ docker exec -it -e VAR4=test_var4 test env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=de9cf4253ae9
TERM=xterm
VAR1=test_var1
VAR2=test_var2
DEBIAN_FRONTEND=teletype
LANG=en_US.UTF-8
LANGUAGE=en_US:en
LC_ALL=en_US.UTF-8
VAR4=test_var4
HOME=/root
cloud_user@vijaygharge1c:/var/lib/docker$ docker exec -it -e VAR4=test_var4 test env | grep VAR
VAR1=test_var1
VAR2=test_var2
VAR4=test_var4
cloud_user@vijaygharge1c:/var/lib/docker$ docker exec -it -e VAR3=test_var3 test env | grep VAR
VAR1=test_var1
VAR2=test_var2
VAR3=test_var3
cloud_user@vijaygharge1c:/var/lib/docker$ 
Docker版本:

cloud_user@vijaygharge1c:/var/lib/docker$ docker -v
Docker version 19.03.12, build 48a66213fe
cloud_user@vijaygharge1c:/var/lib/docker$ 

环境变量的作用域在docker容器的运行时内。 这意味着,当您启动容器时,它将是您在开始时设置的var

容器不是持久的,这意味着,当您在容器中启动一个映像时,它是由scratch创建的,没有关于上次运行的内存


根据您试图实现的目标,您需要另一种解决方案。

将环境变量视为容器中运行的应用程序中存在的任何其他变量。这样一个变量的最后一个值是否会在docker运行期间保持不变没有

如果要跨会话保存修改后的环境变量,则必须在退出容器之前将卷用作持久存储,并将环境变量作为文件存储到卷中

如何创建和使用卷:

$ docker volume create my-vol

$ docker run -itd --rm  --name "test" phusion/baseimage:18.04-1.0.0 --mount source=myvol,target=/app

其余部分由应用程序负责通过FS访问卷并将环境变量保存在其中。应用程序的另一项职责是在启动时访问卷并还原上一个环境变量值。

您必须删除并重新创建容器。还有许多其他Docker选项(卷装载、网络配置、正在运行的实际映像)在创建容器后也无法更改;删除和重新创建容器是非常常规的,您需要在这里执行此操作

具体地说,就环境变量而言,流程的环境是在其初始创建时设置的(更准确地说,是在其前一个execve(2)它)之后,流程可以setenv(3)它自己的环境,但其他任何东西都不能改变它-不是它的父级,也不是它的子级,没有root权限。这是一个通用的Unix语句,并不特定于Docker


在Docker中,还有几个地方环境变化是看不见的。容器中的进程可以更改自己的环境(在入口点脚本中这样做很常见),但这在
docker inspect
输出或
docker exec
shell中不可见。在您的示例中,您是
docker exec
现有容器中的一个新shell,并更改该shell的环境,但这不会更改主容器进程的环境,也不会更改
docker inspect
输出。

谢谢。虽然我同意env不会在docker运行期间持续存在,但是否有任何方法可以覆盖正在运行的容器上的env var,即在停止/删除并重新启动它之前?我试图理解这个概念&没有任何用例。例如,如果db admin的密码由于某些原因被更改-我是否有停止和启动容器来反映新密码?//在停止之前,有没有方法覆盖正在运行的容器上的env var?是-您应该在应用程序中处理SIGTERM并在那里进行更新。但问题是什么?容器终止后,您所做的更改将立即丢失。谢谢。在这种情况下,我不会尝试停止并重新启动容器。我正在研究如何在当前运行的容器中覆盖env,即docker run和docker stop/kill之间。如果我理解正确-一旦流程启动并读取env变量-在其生命周期中稍后更改它们将无关紧要。谢谢你详细介绍。虽然其他的回答都是信息性的,但我将接受这一评论作为答案。