【问题标题】:Update PATH in Centos Docker image (alternative to Dockerfile ENV)更新 Centos Docker 映像中的 PATH(替代 Dockerfile ENV)
【发布时间】:2018-08-16 15:52:49
【问题描述】:

我正在使用 Packer 配置 docker Centos 映像,并使用 bash 脚本而不是 Dockerfile 来配置映像(这似乎是 Packer 的方式)。我似乎无法弄清楚如何更新 PATH 变量,以便我的自定义二进制文件可以像这样执行:

docker run -i -t <container> my_binary

我曾尝试将.sh 文件放入/etc/profile.d/ 文件夹并直接写入/etc/environment,但似乎都没有生效。

我怀疑这与 Docker 在一次性容器中执行命令时使用的 shell 有关。我以为是 Bourne Shell,但如前所述,/etc/profile.d/ 和 /etc/environment 方法都不起作用。

更新:

据我所知,由于@tgogos 回答中解释的原因,无法更改正在运行的容器中的环境变量。但是我不认为这对我来说是个问题,因为在 Packer 完成配置映像之后,它会提交它并上传到 Docker Hub。更准确的例子如下:

$ docker run -itd --name test centos:6
$ docker exec -it test /bin/bash
[root@006a9c3195b6 /]# echo 'echo SUCCESS' > /root/test.sh  
[root@006a9c3195b6 /]# chmod +x /root/test.sh
[root@006a9c3195b6 /]# echo 'export PATH=/root:$PATH' > /etc/profile.d/my_settings.sh
[root@006a9c3195b6 /]# echo 'PATH=/root:$PATH' > /etc/environment
[root@006a9c3195b6 /]# exit
$ docker commit test test-image:1
$ docker exec -it test-image:1 test.sh

期待看到SUCCESS 打印但得到

OCI runtime exec failed: exec failed: container_linux.go:296: starting container process caused "exec: \"test.sh\": executable file not found in $PATH": unknown

更新 2

我已经更新了 ~/.bashrc 中的 PATH,这让我可以执行以下操作:

$ docker run -it test-image:1 /bin/bash
[root@8f821c7b9b82 /]# test.sh 
SUCCESS

但是运行docker run -it test-image:1 test.sh 仍然会导致

docker: Error response from daemon: OCI runtime create failed: container_linux.go:296: ...

我可以确认我的图像 CMD 设置为“/bin/bash”。那么有人能解释一下为什么运行docker run -it test-image:1 test.sh 不来源~/.bashrc 吗?

【问题讨论】:

  • 你能提供一个mcve吗?
  • @tgogos 请查看带有 mcve 示例的更新问题。

标签: docker centos environment-variables packer


【解决方案1】:

这里提到了几个优点:

@BMitch 提到:

销毁您的容器并使用docker run -e ... 使用新环境变量启动一个新容器。这与在正在运行的进程上更改环境变量相同,您将其停止并使用传入的新值重新启动。

在 cmets 部分,他补充道:

Docker 不提供在运行容器中修改环境变量的方法,因为操作系统不提供在运行进程中修改环境变量的方法。您需要销毁并重新创建。

更新:(参见 cmets 部分)

你可以使用

docker commit --change "ENV PATH=your_new_path_here" test test-image:1

【讨论】:

  • 非常感谢您的回复!它为我澄清了一些事情。不幸的是,其中之一是我的“最小、完整和可验证的示例”太小了,不够完整。特别是,在通过 Packer 完成配置后,生成的容器将导出到 Docker Hub。后来,当其他用户尝试使用它并运行my_binary 时,他们就会遇到该二进制文件不在PATH 上的问题。我已经更新了 mcve,如果您能检查我的答案的 UPDATED 2 部分,看看您是否知道该场景的解决方案,我将不胜感激。
  • 对不起,我阅读了您分享的第二篇文章(Docker - 更新容器的环境变量),它似乎与我的场景相似。我的理解是,我应该能够保留在配置步骤中所做的文件系统更改,以便以后使用,我缺少的是这些更改必须是什么。
  • 我看到 PATH 容器变量被保存在 /var/lib/docker/containers/b03d22......./config.v2.json 这就是为什么 github user 建议停止 docker 守护进程,更新文件并重新启动。我不认为这是一个好的解决方案。恐怕您必须 docker run 一个具有您想要的值的新容器(从一开始),因为回想起来无法更改 PATH...
  • 您链接到的github问题仍在谈论修改正在运行的容器。在我的情况下,我想确保在容器提交到图像后环境变量更改仍然存在。
  • 我根据您对docker commit 的要求更新了我的答案。我尝试使用类似:/root:$PATH 但它需要我主机的 PATH 变量。
【解决方案2】:

/etc/profile 仅在登录 shell 调用时由 bash 读取。

有关 bash 在启动时读取哪些文件的更多信息,请参阅article。

编辑:如果您将示例中的最后一行更改为: docker exec -it test bash -lc test.sh 它按您的预期工作。

【讨论】:

  • 感谢您的回复。我尝试在/etc/profile 和/etc/bash.bashrc 中设置PATH(根据您分享的文章,这是Bash 寻找的第一个位置),但没有效果。这让我怀疑以docker run -it &lt;container&gt; my_binary 执行的命令是否在 bash shell 中运行。
  • 另外值得注意的是,test.sh 中没有 she bang,因此它是由 sh 而不是 bash 调用的。
  • 很好的观察,但不是问题,因为它从未真正执行test.sh,因为它不知道在哪里找到它。
  • 因为你从不调用 bash。
  • 所以当test.sh 被调用为docker run -it test-image:1 test.sh 时,“在哪里”(即在什么环境中)被执行?我认为它在/bin/bash 中运行,因为这也是 CMD 设置的。但是重新阅读 Dockerfile 文档后,我不确定情况是否如此。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-27
  • 1970-01-01
  • 2014-11-24
  • 2023-03-09
  • 1970-01-01
相关资源
最近更新 更多