【发布时间】:2016-04-26 23:34:40
【问题描述】:
是否可以将 docker ENV 变量设置为命令的结果? 喜欢:
ENV MY_VAR whoami
我希望 MY_VAR 获得值“root”或 whoami 返回的任何值
【问题讨论】:
标签: dockerfile env
是否可以将 docker ENV 变量设置为命令的结果? 喜欢:
ENV MY_VAR whoami
我希望 MY_VAR 获得值“root”或 whoami 返回的任何值
【问题讨论】:
标签: dockerfile env
我遇到了同样的问题,并找到了通过在 dockerfile 中使用 RUN 命令将环境变量设置为函数结果的方法。
例如,我只需为 Rails 应用程序设置一次 SECRET_KEY_BASE,而无需像运行时那样更改:
docker run -e SECRET_KEY_BASE="$(openssl rand -hex 64)"
相反,我将其写入 Dockerfile 字符串,例如:
RUN bash -l -c 'echo export SECRET_KEY_BASE="$(openssl rand -hex 64)" >> /etc/bash.bashrc'
即使在 bash 登录后,我的 env 变量也可以从 root 获得。 或者可能是
RUN /bin/bash -l -c 'echo export SECRET_KEY_BASE="$(openssl rand -hex 64)" > /etc/profile.d/docker_init.sh'
然后它在 CMD 和 ENTRYPOINT 命令中可用
Docker 将其缓存为层,并且仅在您更改之前的某些字符串时才更改。
您也可以尝试different ways设置环境变量。
【讨论】:
/etc/profile.d/ 中的任何 *.sh 文件都用于填充环境
作为 DarkSideF 答案的补充。
您应该知道 Dockerfile 中的每一行/命令都在另一个容器中运行。
你可以这样做:
RUN export bleah=$(hostname -f);echo $bleah;
这是在单个容器中运行的。
【讨论】:
$bleah 在此 RUN 命令之外的任何地方都不可用,甚至在同一个 dockerfile 的下一行也不可用,更不用说在它所基于的另一个图像中了.此处 docker 确实缺少明显的功能,看起来写入和读取文件是在图像中实际存储(动态)变量并在图像之间传递它们的唯一方法,这似乎超级 hacky。
此时,命令结果可以与RUN export 一起使用,但不能分配给ENV 变量。
【讨论】:
这个答案是对@DarkSideF的回应,
他提出的方法如下,Dockerfile:
RUN bash -l -c 'echo export SECRET_KEY_BASE="$(openssl rand -hex 64)" >> /etc/bash.bashrc'
(在/etc/bash.bashrc中添加导出)
这很好,但环境变量将仅可用于进程 /bin/bash,如果您尝试运行 docker 应用程序,例如 Node.js 应用程序,/etc/bash.bashrc 将被完全忽略,您的应用程序将不会在尝试访问 process.env.SECRET_KEY_BASE 时,您完全不知道 SECRET_KEY_BASE 是什么。
这就是为什么ENV 关键字是每个人都试图在动态命令中使用的原因,因为每次运行容器或使用exec 命令时,Docker 都会检查ENV 并将每个值传递给当前运行的进程(类似于-e)。
一种解决方案是使用包装器(感谢github issue 中的@duglin)。
在您的项目根目录中有一个包装文件(例如envwrapper),其中包含:
#!/bin/bash
export SECRET_KEY_BASE="$(openssl rand -hex 64)"
export ANOTHER_ENV "hello world"
$*
然后在您的 Dockerfile 中:
...
COPY . .
RUN mv envwrapper /bin/.
RUN chmod 755 /bin/envwrapper
CMD envwrapper myapp
【讨论】:
作为对@DarkSideF 答案的补充,如果您想在您的Dockerfile 在构建过程中 中重用先前命令的结果,您可以使用以下解决方法:
例如:
RUN echo "bla" > ./result
RUN echo $(cat ./result)
为了更简洁,您还可以使用以下 gist,它提供了一个名为 envstore.py 的小型 CLI:
RUN envstore.py set MY_VAR bla
RUN echo $(envstore.py get MY_VAR)
或者您可以使用具有类似 CLI 的 python-dotenv 库。
【讨论】:
ENV 交互时遇到了困难。可与RUN 一起使用。
不确定这是否是您要查找的内容,但为了将 ENV vars 或 ARGS 注入您的 .Dockerfile 构建,此模式有效。
在你的 my_build.sh 中:
echo getting version of osbase image to build from
OSBASE=$(grep "osbase_version" .version | sed 's/^.*: //')
echo building docker
docker build -f \
--build-arg ARTIFACT_TAG=$OSBASE \
PATH_TO_MY.Dockerfile \
-t my_artifact_home_url/bucketname:$TAG .
为了在 .Dockerfile 中获取 ARG,sn-p 可能如下所示:
FROM scratch
ARG ARTIFACT_TAG
FROM my_artifact_home_url/bucketname:${ARTIFACT_TAG}
另外,为了在 .Dockerfile 中获取 ENV,sn-p 可能如下所示:
FROM someimage:latest
ARG ARTIFACT_TAG
ENV ARTIFACT_TAG=${ARTIFACT_TAG}
这个想法是您运行 shell 脚本并调用 .Dockerfile,并将 args 作为构建选项传入。
【讨论】:
如果您使用 sh 运行命令,因为它似乎是 docker 中的默认设置。
你可以这样做:
RUN echo "export VAR=`command`" >> /envfile
RUN . /envfile; echo $VAR
这样,您通过将输出重定向到您选择的 env 文件来构建一个 env 文件。它比必须定义配置文件等更明确。
然后,由于该文件可用于其他层,因此可以获取该文件并使用正在导出的变量。创建 env 文件的方式并不重要。
然后,当您完成后,您可以删除该文件,使其对正在运行的容器不可用。
. 是 env 文件的加载方式。
【讨论】: