Dockerfile CMD中.env与docker-compose环境变量未替换如何解决
问题根本原因
你混淆了Docker构建阶段变量和容器运行时变量的作用域:
- Dockerfile里的
ARG指令定义的变量仅在镜像构建过程(RUN/COPY等指令执行阶段)生效,镜像构建完成后ARG变量会被销毁,不会保留到容器运行时 CMD指令是容器启动时才会执行的,此时构建阶段的ARG已经不存在,自然无法替换变量值
解决方法
你可以任选以下两种方案实现需求:
方案1:将ARG转为ENV保留到运行时(适合需要把变量固化到镜像的场景)
修改Dockerfile,在ARG定义后新增ENV指令,把ARG的值赋值给ENV,同时修正目录切换的写法:
FROM ubuntu:latest ARG TOKEN ARG DECK # 新增以下两行,把构建时ARG转为运行时ENV ENV TOKEN=${TOKEN} ENV DECK=${DECK} ...Run Installers and Stuff... COPY . . RUN dotnet publish # 原RUN cd只对当前层生效,切换工作目录请用WORKDIR WORKDIR /DiscordInitiative/bin/Debug/net5.0/publish RUN echo "${TOKEN}" CMD ./DiscordInitiative --token="${TOKEN}" --deck="${DECK}"
如果选择该方案,还需要补充docker-compose配置,把.env变量传递到构建阶段的ARG中:
version: "3" services: discord-initiative-savageworlds: build: context: . # 新增该部分,传递变量到构建阶段 args: - TOKEN=${TOKEN} - DECK=${DECK} environment: - TOKEN=${TOKEN} - DECK=${DECK}
方案2:直接使用docker-compose注入的运行时环境变量(更灵活,推荐,适合密钥这类不希望固化到镜像的变量)
该方案不需要在Dockerfile中定义ARG,直接使用运行时注入的环境变量即可:
- 精简Dockerfile如下:
FROM ubuntu:latest ...Run Installers and Stuff... COPY . . RUN dotnet publish WORKDIR /DiscordInitiative/bin/Debug/net5.0/publish # CMD直接读取运行时注入的环境变量 CMD ./DiscordInitiative --token="${TOKEN}" --deck="${DECK}"
- 你当前的docker-compose.yml配置无需修改,已经实现了把.env中的变量注入到容器运行时环境,容器启动时CMD会自动读取对应值。
内容的提问来源于stack exchange,提问作者Sulli
相关产品推荐
相关产品推荐

