简述Docker的CMD指令 ?
参考回答
CMD 指令是 Dockerfile 中用于指定容器启动时执行的命令。它有三种形式:
1. CMD ["executable", "param1", "param2"]:执行命令并传递参数(推荐形式)。
2. CMD ["param1", "param2"]:为 ENTRYPOINT 提供默认参数。
3. CMD command param1 param2:以 shell 形式执行命令。
CMD 只会在容器启动时运行一次,且可以被 docker run 命令传递的参数覆盖。
详细讲解与拓展
- CMD 的三种形式:
CMD ["executable", "param1", "param2"]:
- 这种形式是最推荐的,遵循 JSON 数组的格式,能够明确指定要执行的命令及其参数,避免了 shell 的影响(例如避免了某些特殊字符的问题)。
- 例如:
CMD ["java", "-jar", "myapp.jar"] - 这条指令会在容器启动时执行
java -jar myapp.jar。
CMD ["param1", "param2"]:
- 这种形式通常与
ENTRYPOINT指令配合使用,为ENTRYPOINT提供默认的参数值。如果容器运行时没有传递参数,CMD提供的参数会被使用。 - 例如:
ENTRYPOINT ["java", "-jar"] CMD ["myapp.jar"] - 如果运行时没有指定其他参数,容器启动后将执行
java -jar myapp.jar。
CMD command param1 param2:
- 这种形式以 shell 方式执行命令,它通过
/bin/sh -c执行命令。因此,命令参数需要被 shell 执行时的特殊字符(如管道符、重定向符等)处理。 - 例如:
CMD java -jar myapp.jar - 这条命令等同于使用 shell 执行
java -jar myapp.jar。
- 注意事项:
CMD指令指定的命令会在容器启动时执行,但如果在docker run中指定了其他命令或参数,它会覆盖CMD指令指定的命令。例如:
docker run my-container some-other-command在这种情况下,
CMD指令会被忽略,some-other-command会作为容器的启动命令。- 如果 Dockerfile 中同时存在
ENTRYPOINT和CMD指令,CMD提供的是默认参数(如果没有在docker run中传递参数的话),而ENTRYPOINT指定的是执行的命令。
- 示例:
假设你有一个简单的 Java 应用,你可以创建如下 Dockerfile:FROM openjdk:11-jre-slim COPY myapp.jar /app/myapp.jar WORKDIR /app CMD ["java", "-jar", "myapp.jar"]这个 Dockerfile 中,
CMD指定了容器启动时执行的命令java -jar myapp.jar。
总结:CMD 指令在 Dockerfile 中用于指定容器启动时执行的默认命令。它有三种形式,可以通过不同的方式传递命令和参数。CMD 指令可以被 docker run 时提供的参数覆盖,因此它主要用于定义容器的默认行为。