引言
-
前面介绍DockerFile文件的时候简单介绍了一下文件末尾
CMD指令的作用,但是在分析一个项目的Dockerfile文件的末尾的时候还是有些看不懂,所以本文详细扒一扒该参数的具体作用 -
下图为Docker容器总结4关于该参数的一个简单介绍
-
下图为我遇到的实际情况。
正文
容器与CMD的关系
- 前面文章我将容器比喻成"压缩胶囊",但其实Docker本身并不是虚拟机,而是进程;
- 那么在启动容器的时候,是需要指定所运行的程序及参数的。
- CMD 指令就是用于指定默认的容器主进程的启动命令的。
CMD的相关介绍
CMD指令的格式有两种格式:- shell 格式:
CMD <命令> - exec格式:CMD ["可执行文件", "参数1", "参数2"...]
- shell 格式:
- 注: 通常Docker中推荐使用exec格式语法,这类格式在解析时会被解析为JSON数组,因此一定要使用双引号 ",而不要使用单引号。(原因可以看下json的组成格式)
- 原因1:shell格式语法下一般会通过
/bin/sh -c来执行命令;例如CMD echo $PATH,其实实际执行过程会变成CMD [ "sh", "-c", "echo $PATH" ],这样的话,环境变量会被 shell 进行解析处理掉 - 原因2:有些镜像是不包含Shell的,那使用shell格式下的命令无法被正常执行。
- 同理使用exec格式时需要获取环境变量的值,如果无法获取则可以考虑使用shell格式语法
- 原因1:shell格式语法下一般会通过
- 注:前面提到过对于CMD指定的命令,参数,不可以通过
docker run命令行实现传递参数。因为命令行参数中指定的命令、参数与其是冲突的,如果命令行有就会把CMD部分覆盖掉
ENTRYPOINT的相关介绍
- 其他的同理,格式同CMD一致,也是有两种方式,shell和exec
- shell格式
ENTRYPOINT 命令 参数1 参数2 - exec格式
ENTRYPOINT ["命令", "参数1", "参数2"] - 同样Docker推荐使用exec格式
- shell格式
- 注:ENTRYPOINT指令其实所设置命令、参数也可被
docker run命令行参数中指定要运行的命令 覆盖, 但需要使用--entrypoint选项进行显式覆盖。否则将会忽略命令行参数(是在命令行使用哈)
组合使用
- 大多数场景下,
CMD、ENTRYPOINT指令都是互相通用的,而且一般也会只使用其中一种指令,实际使用时对于组合使用二者来说,一般是通过exec格式的ENTRYPOINT设置固定的命令、参数,而利用exec格式的CMD设置默认的可变参数; - 换句话说:CMD指令方便镜像使用者更改容器运行的命令,故适用于较为灵活的场景;而如果不期望镜像使用者去轻易更改容器运行的命令,故推荐使用ENTRYPOINT指令;