在使用 Docker 构建镜像时,Dockerfile 中的 CMD 和 ENTRYPOINT 都是用来设置容器的启动命令。然而,它们的作用略有不同。本文将介绍它们之间的区别,以及如何适当地使用它们。
CMD
CMD 是 Dockerfile 中的一个指令,用于设置容器启动后要运行的命令。例如,下面的 CMD 指令设置容器启动后要运行的命令是 npm start
。
CMD ["npm", "start"]
当 Docker 容器启动时,它将使用该命令来启动应用程序。但是,如果使用 docker run
命令时提供了容器命令,它会覆盖 CMD 中的命令。例如,如果你运行下面的命令:
docker run my-image npm run test
它将覆盖 CMD 中的命令,并且容器将运行 npm run test
命令。
ENTRYPOINT
ENTRYPOINT 也是 Dockerfile 中的一个指令,用于设置容器启动后要运行的命令。然而,与 CMD 不同,ENTRYPOINT 中指定的命令不会在容器启动时被覆盖,除非使用 --entrypoint
标志显式指定。
例如,下面的 ENTRYPOINT 指令设置容器启动后要运行的命令是 npm start
。
ENTRYPOINT ["npm", "start"]
当你运行下面的命令时:
docker run my-image npm run test
它将运行 npm start
命令,而不是被覆盖的 npm run test
命令。
CMD 与 ENTRYPOINT 的区别
总的来说,CMD 和 ENTRYPOINT 都用于设置容器启动后运行的命令。但是它们之间有一些重要的区别:
- CMD 可以被容器命令覆盖,而 ENTRYPOINT 不能。
- 如果在 Dockerfile 中同时定义了 CMD 和 ENTRYPOINT,CMD 中的命令将成为 ENTRYPOINT 命令的默认参数。
- 当使用
docker run
命令时,CMD 中的命令可以作为参数传递给 ENTRYPOINT。
最佳实践
在使用 CMD 和 ENTRYPOINT 时,请遵循以下最佳实践:
- 如果你的容器应该始终运行同一个命令,使用 ENTRYPOINT。
- 如果你想在容器运行时提供初始参数,可以使用 CMD 实现更大的灵活性。
- 在定义 Dockerfile 时,使用与Linux命令匹配的形式以及使用 JSON 数组等形式时加上双引号,可以避免一些错误。
下面是一个使用 CMD 和 ENTRYPOINT 的例子,它将在容器启动时运行一个 Node.js 应用程序。
-- -------------------- ---- ------- ---- ------- ------- ---- ---- ------------- -- --- --- ------- ---- - - ------ ---- ---------- ------- -------- --- ---------- --------
这个例子中,ENTRYPOINT 设置了默认的命令 npm start
,而 CMD 则提供了 --name
参数,使用户可以在容器启动时传递参数。例如,下面的命令将在容器启动时运行 npm start
命令,并传递一个名为 Alice 的参数。
docker run my-image --name Alice
结论
CMD 和 ENTRYPOINT 都允许你设置容器启动后要运行的命令,但它们之间有一些重要的区别。正确地使用这两个指令可以在容器中运行应用程序时提供最佳的灵活性和可重用性。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/674c17d814b275ea6fe3dc0e