RUN
在构建过程中在镜像中执行命令。CMD
容器创建时的默认命令。(可以被覆盖)ENTRYPOINT
容器创建时的主要命令。(不可被覆盖)
指令介绍
1.RUN
在构建过程中在镜像中执行命令,是在 docker build中执行
2.CMD
作用:为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。 在docker run 时运行。
注意:如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效。
shell
CMD <shell 命令>
CMD ["<可执行文件或命令>","<param1>","<param2>",...]
CMD ["<param1>","<param2>",...] # 该写法是为 ENTRYPOINT 指令指定的程序提供默认参数
3.ENTRYPOINT
类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。
但是, 如果运行 docker run 时使用了 --entrypoint 选项,将覆盖 ENTRYPOINT 指令指定的程序。
优点:在执行 docker run 的时候可以指定 ENTRYPOINT 运行所需的参数。
注意:如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。
shell
ENTRYPOINT ["<executeable>","<param1>","<param2>",...]
CMD和ENTRYPOINT区别以及搭配使用
ENTRYPOINT
指令和 CMD
指令的工作方式类似,但它们之间有一个关键区别:ENTRYPOINT
指定的程序 不会被 docker run
命令行参数覆盖,而命令行参数 会被当作参数传递给 ENTRYPOINT
指定的程序。
理解示例
1. Dockerfile 示例
假设我们在 Dockerfile
中使用 ENTRYPOINT
指令:
Dockerfile
FROM ubuntu
ENTRYPOINT ["echo", "Hello"]
在这个 Dockerfile
中,echo
是 ENTRYPOINT
指定的程序,而 "Hello"
是它的默认参数。
2. 运行容器时传递参数
当你使用 docker run
运行镜像时,如果你在命令行中传递了额外的参数,这些参数会被附加到 ENTRYPOINT
指定的程序之后,作为它的参数。
例如:
bash
docker run my-ubuntu World
这个命令不会覆盖 ENTRYPOINT
,而是将 World
作为参数传递给 echo
,最终执行的命令是:
bash
echo Hello World
输出结果:
plaintext
Hello World
在这个例子中,docker run my-ubuntu World
将命令行参数 World
传递给了 echo
命令,使得最终的执行效果是输出 Hello World
。
3. 与 CMD 的区别
如果你在 Dockerfile
中使用的是 CMD
而不是 ENTRYPOINT
,那么 docker run
中的参数会完全覆盖 CMD
指定的默认命令。
例如:
Dockerfile
FROM ubuntu
CMD ["echo", "Hello"]
运行 docker run my-ubuntu World
时,World
会覆盖 CMD
中的 echo Hello
,最终执行的命令是:
bash
World
这会导致 docker: Error response from daemon: OCI runtime create failed
的错误,因为 World
不是有效的命令。
4. 结合 CMD
和 ENTRYPOINT
你还可以结合 ENTRYPOINT
和 CMD
来提供更灵活的默认行为。例如:
Dockerfile
FROM ubuntu
ENTRYPOINT ["echo"]
CMD ["Hello"]
在这种情况下,ENTRYPOINT
始终会执行 echo
,而 CMD
中的 "Hello"
是默认参数。如果你运行:
bash
docker run my-ubuntu
输出结果是:
plaintext
Hello
但是,如果你运行:
bash
docker run my-ubuntu World
这时,World
会覆盖 CMD
的 "Hello"
,并作为参数传递给 echo
,输出:
plaintext
World
总结
ENTRYPOINT
不会被docker run
命令行参数覆盖,命令行参数会传递给ENTRYPOINT
指定的程序。CMD
可以被docker run
覆盖,且默认参数会在没有额外命令行参数时生效。