本地机器覆盖的Docker映像环境变量

时间:2020-04-08 21:18:06

标签: bash docker

为什么在检查创建的图像的env时会得到按预期列出的图像环境变量,但是当我尝试访问这些环境变量之一(即$ PATH)时,我会而是获取我的本地计算机环境变量输出?

我相信我误解了docker环境变量的工作方式。我试图对Docker容器运行一些命令,并看到我认为意外的行为。我创建了一个简单的示例来尝试演示。

Dockerfile:

FROM node:12.13.0 

ENV PATH="${PATH}:/custom-path/goes-here"

命令:

  1. docker build . -tag env-test
  2. docker run env-test /bin/bash -c "env"
  3. docker run env-test /bin/bash -c "$PATH"

最后两个命令的预期输出。

  1. docker run env-test /bin/bash -c "env".
...
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/custom-path/goes-here
...
  1. docker run evn-test /bin/bash -c "echo $PATH"
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/custom-path/goes-here

最后两个命令的实际输出

  1. docker run env-test /bin/bash -c "env".
...
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/custom-path/goes-here
...
  1. docker run evn-test /bin/bash -c "echo $PATH"
/Users/local-machine-user/Downloads/google-cloud-sdk/bin:/Users/local-machine-user/.nvm/versions/node/v12.16.1/bin:/Library/Frameworks/Python.framework/Versions/3.7/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin:/Users/local-machine-user/Downloads/google-cloud-sdk/bin:/Library/Frameworks/Python.framework/Versions/3.7/bin

针对创建的映像运行echo $PATH的输出将返回我的本地计算机$ PATH变量。什么?

我要做的主要事情是针对docker映像执行一个脚本,该脚本需要我在映像中设置的那些环境变量,但是该脚本失败了,因为该脚本使用的环境变量最终用于我的本地计算机,并且不是图片中指定的图片。

2 个答案:

答案 0 :(得分:1)

在字符串中使用$PATH-"echo \$PATH"

时,您应转义美元符号

在运行此行时会发生什么:

docker run evn-test /bin/bash -c "echo $PATH"

Bash首先翻译$PATH,然后将该字符串传递到docker容器中。因此,在容器内运行的命令是:

docker run evn-test /bin/bash -c "echo /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

答案 1 :(得分:1)

假设您要运行第三个示例

docker run env-test /bin/bash -c "echo $PATH"

这里发生的第一件事是您的本地shell处理此命令并执行其通常的扩展集。例如,扩展双引号中的环境变量引用。构建最终的命令行后,shell便会执行它。

通常有用的技巧是将echo放在命令的前面

echo docker run env-test /bin/bash -c "echo $PATH"

这将向您显示本应运行但实际上未运行的命令。

要执行此操作,您需要使本地外壳程序不扩展环境变量,以便您在容器中启动的外壳程序可以执行此操作。单引号或反斜杠转义都适用于此

docker run env-test /bin/sh -c 'echo $PATH'
docker run env-test /bin/sh -c "echo \$PATH"

我要做的主要事情是针对docker映像执行一个脚本,该脚本需要在映像中设置的那些环境变量

解决此问题的最佳方法可能是编写一个普通的Shell脚本并将其COPY插入图像。这节省了报价和混淆的层,在哪一层外壳正在处理变量之类的东西。如果您无法修改映像,则可以选择从主机绑定挂载脚本。

# If the script is in the image
docker run --rm env-test path-echoer.sh

# If not
docker run --rm -v $PWD:/scripts env-test /scripts/path-echoer.sh