Docker/SBT中Cmd与ExecCmd的区别及与RUN等指令的组合方法
sbt-native-packager中Cmd与ExecCmd的区别及Docker指令结合方式
核心区别
- Cmd:直接将传入的参数拼接成完整的Docker指令,不做额外格式转换,适合所有类型的Docker指令(包括构建阶段和启动阶段)。它会把参数按空格拼接成一行Dockerfile语句。
- ExecCmd:专门用于生成Docker的exec格式指令(即JSON数组形式),仅适用于容器启动阶段的
ENTRYPOINT和CMD。它要求传入的参数是命令和其拆分后的独立参数列表,自动转换成JSON数组格式,不支持构建阶段的RUN指令。
与Docker RUN、ENTRYPOINT、CMD的结合方式
1. 构建阶段指令(RUN)
只能使用Cmd,因为ExecCmd不支持构建阶段的RUN操作:
dockerCommands += Cmd("RUN", "yum install -y git")
对应生成的Dockerfile内容:
RUN yum install -y git
2. 容器启动指令(ENTRYPOINT/CMD)
用Cmd生成shell格式指令
指令会在shell环境中执行,适合需要shell特性(比如环境变量展开)的场景:
dockerCommands += Cmd("ENTRYPOINT", "java -jar /app/myapp.jar")
对应Dockerfile:
ENTRYPOINT java -jar /app/myapp.jar
用ExecCmd生成exec格式指令
指令以JSON数组形式存在,直接执行命令(不经过shell),适合需要精确控制参数、避免shell干扰的场景:
dockerCommands += ExecCmd("ENTRYPOINT", "java", "-jar", "/app/myapp.jar")
对应Dockerfile:
ENTRYPOINT ["java", "-jar", "/app/myapp.jar"]
CMD指令同理:
// shell格式 dockerCommands += Cmd("CMD", "--port 8080") // exec格式 dockerCommands += ExecCmd("CMD", "--port", "8080")
你的问题解释
你用ExecCmd("RUN", "yum install git")报错,本质是ExecCmd的设计定位是容器启动阶段的exec格式指令,不支持构建阶段的RUN操作。而Cmd是通用指令生成器,能适配所有Docker指令类型,所以可以正常生成RUN语句完成git安装。
内容的提问来源于stack exchange,提问作者Dan Ciaolo
相关产品推荐
相关产品推荐

