如何在正在运行的docker容器中设置环境变量

Spe*_*ley 50 docker

如果我有一个我开始使用的docker容器,那么在该运行容器中设置环境变量的最佳方法是什么?我在运行run命令时最初设置了一个环境变量.

$ docker run --name my-wordpress -e VIRTUAL_HOST=domain.com --link my-mysql:mysql -d spencercooley/wordpress
Run Code Online (Sandbox Code Playgroud)

但是现在它已经运行了一段时间我想VIRTUAL_HOST在环境变量中添加另一个.我不想删除容器,然后只使用我想要的环境变量重新运行它,因为那时我必须将旧卷迁移到新容器,它有主题文件和上传,我不想要输.

我只想改变VIRTUAL_HOST环境变量的值.

小智 33

通常有两个选项,因为docker现在不支持此功能:

  1. 创建自己的脚本,它将像您的命令一样运行.例如:

    #!/bin/bash
    export VAR1=VAL1
    export VAR2=VAL2
    your_cmd
    
    Run Code Online (Sandbox Code Playgroud)
  2. 按以下方式运行命令:

    docker exec -i CONTAINER_ID /bin/bash -c "export VAR1=VAL1 && export VAR2=VAL2 && your_cmd"
    
    Run Code Online (Sandbox Code Playgroud)

  • 现在它已经有大约2.5年了,这仍然是最好的做事方式还是码头工人允许更直接的方法? (8认同)
  • 尝试`docker exec -it CONTAINER_ID /bin/bash -c "export VAR=1 && echo $VAR"` 它输出空白变量(预期为`1`)。我错过了什么? (3认同)
  • @yellow01 当你像 `"... echo $VAR"` 中的双引号变量引用时,变量在你当前的 shell 环境中解析,在这种情况下是你的 Docker 主机。例如,您可以通过尝试 `echo $HOSTNAME` 来证明这一点,该值将是您的 Docker 主机的主机名。尝试单引号该命令字符串以获得您想要的效果。 (3认同)
  • 如果您允许容器始终“重新启动”,如果该容器出现问题并自动重新启动,那么环境变量将会是什么? (3认同)

Bry*_*yan 15

Docker不提供此功能.

有一个问题:" 如何在现有容器上设置环境变量?#8838 "

同样来自" 允许docker start采取环境变量#7561 ":

现在,Docker一旦创建就无法更改容器的配置,通常这是可以的,因为创建一个新容器很简单.

  • 令我惊讶的是,7 年后,Docker 仍然没有解决这个问题。 (3认同)
  • 啊,真糟糕。我会想办法的。制作一个新容器很简单,但从旧容器中取出卷并将它们挂载到新容器中并非易事。我不想丢失我的 wp-content 目录。手动移动卷确实并不难,但我正在尝试使事情自动化,因此它有点违背了目的。也许我可以编写一个 Python 函数来执行此操作。https://gist.github.com/anonymous/68f4138261fdb73a6e79 (2认同)

Ard*_*dan 11

以下是如何修改正在运行的容器以更新其环境变量。这假设您在 Linux 上运行。我用 Docker 19.03.8 测试了它

实时恢复

首先,确保您的 Docker 守护进程设置为在关闭时让容器保持运行。编辑您的/etc/docker/daemon.json, 并添加"live-restore": true为顶级密钥。

sudo vim /etc/docker/daemon.json
Run Code Online (Sandbox Code Playgroud)

我的文件如下所示:

{
    "default-runtime": "nvidia",
    "runtimes": {
        "nvidia": {
            "path": "nvidia-container-runtime",
            "runtimeArgs": []
        }
    },
    "live-restore": true
}
Run Code Online (Sandbox Code Playgroud)

取自这里

获取容器ID

保存要编辑的容器的 ID,以便更轻松地访问文件。

export CONTAINER_ID=`docker inspect --format="{{.Id}}" <YOUR CONTAINER NAME>`
Run Code Online (Sandbox Code Playgroud)

编辑容器配置

编辑配置文件,转到“Env”部分,然后添加您的密钥。

sudo vim /var/lib/docker/containers/$CONTAINER_ID/config.v2.json
Run Code Online (Sandbox Code Playgroud)

我的文件如下所示:

...,"Env":["TEST=1",...
Run Code Online (Sandbox Code Playgroud)

停止和启动 Docker

我发现重新启动 Docker 不起作用,我必须停止然后用两个单独的命令启动 Docker。

sudo systemctl stop docker
sudo systemctl start docker
Run Code Online (Sandbox Code Playgroud)

由于live-restore,您的容器应该保持运行状态。

验证它是否有效

docker exec <YOUR CONTAINER NAME> bash -c 'echo $TEST'
Run Code Online (Sandbox Code Playgroud)

单引号在这里很重要。

您还可以验证容器的正常运行时间没有改变:

docker ps
Run Code Online (Sandbox Code Playgroud)


小智 8

到:

  1. 设置了许多环境。一步到位,
  2. 防止将它们暴露在 'sh' 历史记录中,例如使用 '-e' 选项(传递凭据/api 令牌!),

您可以使用

--env-file key_value_file.txt

选项:

docker run --env-file key_value_file.txt $INSTANCE_ID
Run Code Online (Sandbox Code Playgroud)

  • “在(已经)运行的 docker 容器中” (2认同)

mkn*_*cht 7

对于一个有点狭窄的用例,docker issue 8838提到了这种类型的hack:

你只需停止docker守护进程并在/var/lib/docker/containers/[container-id]/config.json(sic)中更改容器配置

此解决方案更新环境变量,而无需删除和重新运行容器,必须迁移卷并记住参数run.

但是,这需要重新启动docker守护程序.并且,直到问题2658得到解决,这包括重新启动所有容器.


h3n*_*rik 6

您写道您不想迁移旧卷。因此,我假设Dockerfile您用于构建spencercooley/wordpress映像的 s 已VOLUME定义,或者您使用开关在命令行上指定了它们-v

--volumes-from您可以简单地启动一个新容器,使用以下开关从旧容器导入卷:

$ docker run --name my-new-wordpress --volumes-from my-wordpress -e VIRTUAL_HOST=domain.com --link my-mysql:mysql -d spencercooley/wordpres
Run Code Online (Sandbox Code Playgroud)

因此,您将拥有一个新的容器,但不会丢失旧数据。您甚至不需要触摸或迁移它

一个做得好的容器总是无状态的。这意味着它的进程应该只添加或修改定义卷上的文件。docker diff <containerId>容器运行一段时间后可以通过简单的验证来验证这一点。

在这种情况下,当您使用相同的参数(在您的情况下稍微修改过的参数)重新创建容器时并不危险。假设您从创建旧镜像的完全相同的镜像创建它,并且通过上述开关重新使用相同的卷。

新容器成功启动并且您验证一切运行正常后,您可以删除旧的 WordPress 容器。然后,旧卷将从新容器引用,并且不会被删除。


Aar*_*_ab 5

如果您将容器作为serviceusing运行docker swarm,则可以执行以下操作:

docker service update --env-add <you environment variable> <service_name>

也删除使用 --env-rm

要确保按您的需要添加它,只需运行: docker exec -it <container id> env