Dockerfile传递ARG参数到ENTRYPOINT/CMD不生效问题咨询
核心原因
Docker的CMD/ENTRYPOINT指令有两种格式,变量解析失效的核心是exec格式不会触发shell变量替换:
- 带方括号的
["命令", "参数"]属于exec格式:Docker会直接启动指定程序,不会额外启动shell进程,因此不会做环境变量解析、通配符匹配这类shell专属操作,你写的${profile}会被当成纯字符串传递给程序,自然不生效。 - 不带方括号的
CMD java -jar xxx属于shell格式:Docker会自动以sh -c "你写的整条命令"的逻辑执行,会启动shell进程,因此可以正常解析你提前定义的ENV变量,这也是你补充测试的写法可以正常运行的原因。
各失效写法的具体说明
- 注释掉的exec格式ENTRYPOINT:
ENTRYPOINT ["java", "-jar", "app.jar", "--spring.profiles.active=${profile}"],因为是exec格式无法解析变量,所以失效。 - 最后一行的
CMD ["sh", "-c", "node server.js ${profile}"]失效是因为你用的基础镜像是openjdk的jre镜像,镜像内没有安装node环境,且你实际是Java应用,启动命令写错了,不是变量替换的问题。
正确写法参考
如果你想要用exec格式保证进程信号传递正常(比如可以响应docker stop的SIGTERM信号),可以按下面的方式写:
# Java应用的exec格式写法,可正常解析profile变量 ENTRYPOINT ["sh", "-c", "java -jar app.jar --spring.profiles.active=${profile}"]
如果你不需要严格的进程信号控制,直接用你测试通过的shell格式CMD java -jar app.jar --spring.profiles.active=$profile即可。
内容的提问来源于stack exchange,提问作者Padi
相关产品推荐
相关产品推荐

