Docker系列(三)-容器启动讨论
Contents
ENTRYPOINT vs CMD
其实网上已经有许多关于entrypoint与cmd的比较介绍了, 英文中我主要参考了官方文档解释与docker-run-vs-cmd-vs-entrypoint.
文档中是这么说的:
1 | An ENTRYPOINT allows you to configure a container that will run as an executable. |
允许你将容器变成类似可执行文件的运行方式.
1 | Command line arguments to docker run <image> will be appended after all elements in an exec form ENTRYPOINT, and will override all elements specified using CMD. |
docker run <image>
之后的参数都会作为entrypoint
的参数并且把CMD
命令覆盖掉.
下面将会举几个例子, 其中也会包含一些操作:
只有entrypoint
1 | FROM debian:buster-slim |
可以使用下面两个命令对比下效果
1 | docker run -ti test |
CMD与entrypoint配合使用
1 | FROM debian:buster-slim |
直接运行该容器, 效果其实是和
htop -C
一样的.
1 | docker run -ti test |
当然也有人这样用:
1 | ENTRYPOINT ["echo", "hello"] |
当然会得到hello world
这样的结果, 你可以理解为ENTRYPOINT
和CMD
共同组成了一条命令, 我们在使用docker run
时, 镜像名后面的会被认为是CMD
并将Dockerfile中的默认CMD替换掉.
那么, 现在就有一个问题了, 怎么替换entrypoint呢?
启动时替换entrypoint
答案是--entrypoint
参数, 注意写在镜像名称前面, 写在后面会被当成是CMD.
1 | docker run -ti --entrypoint=/bin/bash <image> |
一般什么时候会替换CMD或是ENTRYPOINT呢?
这样的用法一般用于调试镜像.
编写完Dockerfile后, 无法确定自己的entrypoint与cmd命令正确与否
对于某些无法直接运行的镜像, 需要hack进入镜像, 然后手动的执行命令, 相比于 看日志, 这个应该调试起来更快.
一个比较简单的ENTRYPOINT写法
从上面的描述中已经可以看出, Docker默认的运行方式是依靠ENTRYPOINT与CMD结合使用的. 所以我们在编写ENTRYPOINT时, 顺便考虑一下CMD的运行可能更好.
下面是我常用的一个entrypoint.sh
:
1 |
|
这个entrypoint.sh
主要用于在运行时确保某个目录被挂载, 而后的exec "$@"
会直接运行CMD
.