Dockerfile - 将ENV设置为命令结果

问题描述 投票:48回答:6

是否可以将docker ENV变量设置为命令的结果?喜欢:

ENV MY_VAR whoami

我希望MY_VAR获得值“root”或者任何whoami返回的值

dockerfile env
6个回答
14
投票

作为DarkSideF的补充答案。

您应该知道Dockerfile中的每一行/命令都在另一个容器中运行。

你可以这样做:

RUN export bleah=$(hostname -f);echo $bleah;

这是在一个容器中运行。


12
投票

我有同样的问题,并找到了通过在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'

我的env变量可以从root获得,即使在bash登录后也是如此。或者可能

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来设置环境变量。


7
投票

此时,命令结果可以与RUN export一起使用,但不能分配给ENV变量。

已知问题:https://github.com/docker/docker/issues/29110


4
投票

这个答案是对@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将被完全忽略,你的应用程序将不会有任何一个线索什么SECRET_KEY_BASE是在试图访问process.env.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

2
投票

作为@DarkSideF答案的补充,如果您想在构建过程中在Dockerfile中重用上一个命令的结果,可以使用以下解决方法:

  1. 运行命令,将结果存储在文件中
  2. 使用命令替换将该文件的先前结果转换为另一个命令

例如 :

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库。


2
投票

不确定这是否是您正在寻找的,但为了将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,代码段可能如下所示:

FROM scratch
ARG ARTIFACT_TAG
FROM my_artifact_home_url/bucketname:${ARTIFACT_TAG}

或者,为了在.Dockerfile中获取ENV,该代码段可能如下所示:

FROM someimage:latest
ARG ARTIFACT_TAG
ENV ARTIFACT_TAG=${ARTIFACT_TAG}

我们的想法是运行shell脚本,并使用作为构建选项传入的args调用.Dockerfile。

© www.soinside.com 2019 - 2024. All rights reserved.