Dockerfile - 将 ENV 设置为命令的结果



是否可以将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中重用上一个命令的结果,可以使用以下解决方法:

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

例如:

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 一起存储在环境变量中,以便以后轻松访问,但命令本身的结果不会保存为

相关内容

  • 没有找到相关文章

最新更新