是否可以将docker ENV变量设置为命令的结果?喜欢:
ENV MY_VAR whoami
我希望MY_VAR获得值"root"或任何 whoami 返回的内容
作为DarkSideF答案的补充。
您应该知道,Dockerfile 中的每一行/命令都在另一个容器中运行。
你可以做这样的事情:
RUN export bleah=$(hostname -f);echo $bleah;
这是在单个容器中运行的。
此时,命令结果可以与 RUN export
一起使用,但不能分配给 ENV
变量。
已知问题:https://github.com/docker/docker/issues/29110
我遇到了同样的问题,并找到了通过使用 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 和入口点命令中可用
Docker 将其缓存为层,并且仅当您更改它之前的某些字符串时才更改。
您也可以尝试不同的方法来设置环境变量。
如果您使用 sh 运行命令,因为它似乎是 docker 中的默认值。
你可以做这样的事情:
RUN echo "export VAR=`command`" >> /envfile
RUN . /envfile; echo $VAR
....
RUN . /envfile; echo $VAR # can be re-used
这样,您可以通过将输出重定向到您选择的 env 文件来构建 env 文件。它比必须定义配置文件等更明确。
然后,由于该文件可供其他图层使用,因此可以获取该文件并使用正在导出的变量。创建 env 文件的方式并不重要。
完成后,您可以删除该文件,使其对正在运行的容器不可用。
.
是 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 问题中归功于@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)
对于更简洁的内容,您还可以使用以下要点,它提供了一个名为 envstore.py
的小 CLI:
RUN envstore.py set MY_VAR bla
RUN echo $(envstore.py get MY_VAR)
或者你可以使用python-dotenv库,它有一个类似的CLI。
不确定这是否是您要查找的,但是为了将 ENV 变量或 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 代码段可能如下所示:
FROM scratch
ARG ARTIFACT_TAG
FROM my_artifact_home_url/bucketname:${ARTIFACT_TAG}
或者,在您的 .Dockerfile 代码段可能如下所示:
FROM someimage:latest
ARG ARTIFACT_TAG
ENV ARTIFACT_TAG=${ARTIFACT_TAG}
这个想法是运行 shell 脚本并调用 .Dockerfile,其中args作为构建中的选项传入。
ARG KUBERNETES_VERSION="v1.25.2"
ENV ARCH_CMD='eval uname -m | grep -q x86_64 && echo "amd64" || echo "arm64"'
RUN curl -k -L "https://dl.k8s.io/release/$KUBERNETES_VERSION/bin/linux/$($ARCH_CMD)/kubectl" -o /usr/local/bin/kubectl
&& chmod +x /usr/local/bin/kubectl
基本上将命令与 eval 一起存储在环境变量中,以便以后轻松访问,但命令本身的结果不会保存为