如何在Dockerfile的ENTRYPOINT、CMD指令中使用ENV环境变量
Dockerfile 中 ENTRYPOINT、CMD 指令使用 ENV 环境变量的解决方案
问题根因
Docker 的 RUN、CMD、ENTRYPOINT 指令支持两种书写格式,变量无法识别通常是格式选择导致的:
- exec 格式:写法为
CMD ["可执行文件", "参数1", "参数2"],该格式不会触发 shell 解析,会直接将${变量名}作为普通字符串传递,因此无法读取 ENV 定义的环境变量。 - shell 格式:写法为
CMD 可执行文件 参数1 参数2,该格式底层会自动调用/bin/sh -c执行命令,默认支持环境变量解析。如果该格式依然无法识别变量,通常是基础镜像缺少默认 shell 导致,你使用的openjdk:11-jdk-slim-buster为 Debian 系镜像,默认携带 shell,不存在该问题。
可用实现方案
方案1:exec 格式主动调用 shell 解析
如果需要使用 exec 格式(保证进程为 PID 1、可正常接收系统停止信号),可以主动指定 shell 做变量解析,写法如下:
# CMD 写法 CMD ["sh", "-c", "java -jar /app/$JAVA_APP.jar"] # ENTRYPOINT 写法 ENTRYPOINT ["sh", "-c", "java -jar /app/$JAVA_APP.jar"]
方案2:直接使用标准 shell 格式
去掉指令的方括号,使用原生 shell 格式,Docker 会自动完成变量解析:
CMD java -jar /app/$JAVA_APP.jar
方案3:支持额外传参的混合写法
如果需要后续通过 CMD 或者启动命令追加额外参数,可以用如下写法,保证变量解析和参数传递同时生效:
ENTRYPOINT ["sh", "-c", "java -jar /app/$JAVA_APP.jar \"$@\"", "--"] # 可以追加默认参数,也可以启动容器时覆盖 CMD ["--spring.profiles.active=prod"]
内容的提问来源于stack exchange,提问作者Teofilo
相关产品推荐
相关产品推荐

