【docker】Dockerfile中ENTRYPOINT和CMD区别理解
1. ENTRYPOINT
和 CMD
的作用:
-
ENTRYPOINT
: 设置容器启动时执行的主命令。它通常用来定义容器的主要行为或者应用的主进程,容器启动时会默认执行该命令。ENTRYPOINT
设置的命令不可被覆盖,但可以通过传递额外的参数来改变其行为。 -
CMD
: 为ENTRYPOINT
提供默认的参数。如果CMD
和ENTRYPOINT
都存在,并且CMD
没有参数,CMD
会被作为默认参数传递给ENTRYPOINT
。如果容器运行时没有提供额外的命令或参数,CMD
会作为容器默认运行的命令。
2. 语法和例子:
使用 ENTRYPOINT
:
ENTRYPOINT
可以有两种语法:
-
exec 形式(推荐使用)
ENTRYPOINT ["executable", "param1", "param2"]
这种方式会将命令和参数作为数组传递给容器,避免使用 shell 运行,确保信号正确传递。
-
shell 形式
ENTRYPOINT command param1 param2
这种方式会通过 shell 执行命令,类似于在终端中运行命令。
使用 CMD
:
-
CMD 作为命令:
CMD ["executable", "param1", "param2"]
这是给
ENTRYPOINT
提供默认参数,或者如果没有ENTRYPOINT
,则作为默认命令执行。 -
CMD 作为 shell 命令:
CMD ["param1", "param2"]
-
CMD 作为单独的命令(如果没有
ENTRYPOINT
):CMD ["executable", "param1", "param2"]
综合使用 ENTRYPOINT
和 CMD
:
- 当同时使用
ENTRYPOINT
和CMD
时,CMD
会作为参数传递给ENTRYPOINT
。如果容器启动时没有其他命令行参数,CMD
中的默认参数会被使用。
# 示例 1:使用 ENTRYPOINT 和 CMD
FROM ubuntu:20.04
# 设置容器的默认命令
ENTRYPOINT ["python3", "app.py"]
# 设置默认参数
CMD ["--port", "8080"]
在这个例子中,当容器启动时,默认执行的是 python3 app.py --port 8080
,如果在启动容器时提供了额外的参数(例如 docker run my_image --port 9090
),那么 --port 9090
会替代 CMD
中的默认参数 --port 8080
。
3. ENTRYPOINT
与 CMD
的区别:
特性 | ENTRYPOINT | CMD |
---|---|---|
功能 | 定义容器启动时要执行的主命令或程序。 | 提供默认的命令或参数(如果没有提供命令时)。 |
行为 | 容器启动时,ENTRYPOINT 设置的命令始终执行。 | 如果没有指定其他命令,CMD 会作为默认命令执行。 |
覆盖 | 不容易被覆盖,除非使用 docker run 时明确指定命令。 | 容器启动时,如果没有指定命令,CMD 会作为默认值。 |
语法 | ENTRYPOINT ["executable", "param1", "param2"] | CMD ["param1", "param2"] |
灵活性 | 固定性更强,通常用于关键应用程序的启动。 | 更灵活,可以被用户在 docker run 时覆盖。 |
结合使用 | CMD 可以提供默认参数给 ENTRYPOINT 。 | CMD 可以提供默认命令或者覆盖 ENTRYPOINT 。 |
4. 实际例子:
例子 1:仅使用 ENTRYPOINT
FROM ubuntu:20.04
ENTRYPOINT ["echo", "Hello"]
运行这个容器时,默认会输出 Hello
。
例子 2:使用 ENTRYPOINT
和 CMD
FROM ubuntu:20.04
ENTRYPOINT ["echo"]
CMD ["Hello World"]
如果不传递其他命令参数,运行容器时默认会输出 Hello World
。但如果通过 docker run
传递其他参数(如 docker run my_image Goodbye
),则会输出 Goodbye
。
总结:
ENTRYPOINT
适用于指定容器启动时始终执行的主命令或程序,适合核心应用程序。CMD
用于提供默认参数或默认命令,具有更高的灵活性,可以通过运行时参数覆盖。
https://github.com/0voice