基于 build ARG 有条件地在 Dockerfile 中设置 ENV vars

Posted

技术标签:

【中文标题】基于 build ARG 有条件地在 Dockerfile 中设置 ENV vars【英文标题】:Conditionally setting ENV vars in Dockerfile based on build ARG 【发布时间】:2019-07-06 10:38:23 【问题描述】:

我想根据某些构建 ARG 在我的 Dockerfile 中有条件地设置一些 ENV 变量。由于某种原因,ENV var 没有直接映射到实际的构建 ARG,即我不能执行以下操作:

ARG myvar
ENV MYVAR $MYVAR

这是一个足够复杂的映射,我不能只做,比如“prefix-$$MYVAR”,或者其他什么。

我知道只使用带有 EXPORT 的 shell 命令(然后可以访问 if 语句),但是以这种方式导出环境变量不会像我需要的那样在容器中持续存在。如果唯一的解决方案是为我需要的每个 RUN/CMD 重复添加所需的 env 前缀(以及到达那里所需的所有逻辑),那么我会接受。

我也知道这个答案Conditional ENV in Dockerfile,它确实有一个解决方案,其中(基本上)三元用于触发某个 ENV 值,但因为我的情况更复杂,我不能只使用它给定的解决方案。

有没有办法在 Dockerfile 中编写“逻辑”,同时仍然可以访问 ENV 等 Docker 命令?

任何帮助将不胜感激!

PS。

这是一个构建Node镜像的Dockerfile,所以我最后几步看起来基本像

RUN npm run build
CMD ["npm", "run", "start"]

【问题讨论】:

【参考方案1】:

我在容器上设置代理服务器时遇到了类似的问题。

我使用的解决方案是一个入口点脚本,以及另一个用于环境变量配置的脚本。使用 RUN,您可以确保配置脚本在构建时运行,并在您运行容器时确保 ENTRYPOINT。

入口点脚本如下所示:

#!/bin/bash
    
# Run any other commands needed 

# Run the main container command
exec "$@"

在 Dockerfile 中,配置:

#copy bash scripts
COPY configproxy.sh /root
COPY startup.sh .    
RUN ["/bin/bash", "-c", ". /root/configproxy.sh"]
ENTRYPOINT ["./entrypoint.sh"]
CMD ["sh", "-c", "bash"]

看看here。

【讨论】:

【参考方案2】:

如果我正确理解你的问题,你想要

if BUILD_VAR == v1:
  set ENV MYVAR=aValue
else if YOUR_VAR == v2:
  set ENV MYVAR=anotherValue

解决方案:

ARG BUILD_VAR=v1

FROM scratch as build_v1
ONBUILD ENV MYVAR=aValue

FROM scratch as build_v2
ONBUILD ENV MYVAR=anotherValue

FROM build_$YOUR_VAR AS final
...
RUN npm run build
CMD ["npm", "run", "start"]

***BUILD_VAR 允许您通过docker build --build-arg BUILD_VAR=v1 . 的条件

使用ONBUILD,所以指令ENV只有在选择了相应的分支时才会执行。

【讨论】:

哇,我不知道 ONBUILD 指令,谢谢!请给我一点时间来测试一下,然后我会标记为正确的。 对我不起作用:Step 12/18 : FROM simd_$SIMD as final invalid reference format 已修复。 ARG YOUR_VAR 必须在第一个 FROM 之前声明。

以上是关于基于 build ARG 有条件地在 Dockerfile 中设置 ENV vars的主要内容,如果未能解决你的问题,请参考以下文章

docker build with --build-arg 带有多个参数

有条件地在 docker-compose 中挂载卷

docker build 使用代理构建镜像

docker build 命令

Docker命令详解(build篇)

Docker命令之 build