dockerfile cmd vs entrypoint区别
在 Dockerfile
中,CMD
和 ENTRYPOINT
都用于定义容器启动时运行的命令或程序,但它们有不同的作用和行为。理解它们的区别对于编写灵活的 Docker 容器非常重要。
1. CMD(默认命令)
CMD
用于为容器提供默认的命令和参数。这意味着,当容器启动时,如果没有指定其他命令,它将使用CMD
中指定的命令和参数。- 注意:如果在
docker run
命令中提供了额外的命令或参数,CMD
将被覆盖。
语法:
- **CMD [“executable”, “param1”, “param2”]**:exec 格式,推荐使用这种方式,因为它不会启动一个额外的 shell 进程。
- **CMD [“param1”, “param2”]**:如果使用
ENTRYPOINT
来定义执行的程序,那么CMD
可以提供默认的参数。 - **CMD [“executable param1 param2”]**:shell 格式,这种方式会启动一个 shell 来执行命令(例如
/bin/sh -c
),有时可能会带来一些副作用,比如信号处理等。
示例:
1 | CMD ["echo", "Hello, World!"] |
如果你运行:
1 | docker run <image_name> |
容器会执行 echo "Hello, World!"
。
如果你运行:
1 | docker run <image_name> echo "Hello, Docker!" |
容器会执行 echo "Hello, Docker!"
,并覆盖 CMD
中的命令。
2. ENTRYPOINT(入口命令)
ENTRYPOINT
用于指定容器启动时运行的主要命令。它确保容器总是执行特定的命令,即使你在docker run
命令中传递了其他参数,也会传递给ENTRYPOINT
。ENTRYPOINT
可以通过两种方式定义:exec
格式(推荐)和shell
格式。ENTRYPOINT
与CMD
的关系:- 如果同时使用
ENTRYPOINT
和CMD
,CMD
提供的参数会被附加到ENTRYPOINT
中。 - 如果没有指定
CMD
,ENTRYPOINT
会直接使用默认参数。
- 如果同时使用
语法:
- **ENTRYPOINT [“executable”, “param1”, “param2”]**:exec 格式,推荐使用。
- **ENTRYPOINT [“executable param1 param2”]**:shell 格式,会启动一个 shell 来执行命令。
示例:
1 | ENTRYPOINT ["echo"] |
这时,默认会执行 echo Hello, World!
。如果运行:
1 | docker run <image_name> "Hello, Docker!" |
容器会执行 echo "Hello, Docker!"
,而 CMD
的默认参数会被覆盖。
3. CMD
和 ENTRYPOINT
配合使用
当你同时使用 CMD
和 ENTRYPOINT
时,ENTRYPOINT
会指定要执行的命令,而 CMD
可以指定默认的参数。如果 docker run
提供了新的参数,这些参数将会替代 CMD
中的参数。
示例:
1 | ENTRYPOINT ["echo"] |
如果运行:
1
docker run <image_name>
容器将执行
echo Hello, World!
。如果运行:
1
docker run <image_name> "Hello, Docker!"
容器将执行
echo Hello, Docker!
,覆盖了CMD
中的默认参数。
4. 总结
特性 | CMD |
ENTRYPOINT |
---|---|---|
目的 | 提供默认的执行命令或参数 | 指定容器启动时始终执行的命令 |
覆盖行为 | 如果 docker run 中提供了其他命令,CMD 会被覆盖 |
ENTRYPOINT 不会被覆盖,CMD 提供附加的参数 |
常见用途 | 提供默认命令或参数,当没有额外命令时执行 | 定义容器启动时必须执行的主命令 |
使用方式 | CMD ["executable", "param1", "param2"] 或 CMD ["param1", "param2"] |
ENTRYPOINT ["executable", "param1", "param2"] |
5. 使用场景:
**
CMD
**:- 用于设置默认命令和参数,当没有指定其他命令时执行。
- 适用于那些可以被用户自定义命令或参数覆盖的场景。
**
ENTRYPOINT
**:- 用于设置容器的主命令,确保容器始终执行指定的命令。
- 适用于那些不想让容器的主命令被覆盖的场景。
**
CMD
+ENTRYPOINT
**:- 用于定义主命令并提供默认参数,同时允许通过
docker run
提供不同的参数来替换默认值。
- 用于定义主命令并提供默认参数,同时允许通过