Dockerfile文件中通过CMD、ENTRYPOINT启动tomcat注意事项,容器启动后就马上退出问题讲解
在上一篇文章中使用Dockerfile制作tomcat镜像,我们在Dockerfile文件中通过ENTRYPOINT /usr/local/tomcat.sh start && tail -f /usr/local/apache-tomcat-8.0.50/logs/catalina.out这个命令进行tomcat的启动,这样做是没有问题的。现在将这块容易出现的问题进...
在上一篇文章中使用Dockerfile制作tomcat镜像,我们在Dockerfile文件中通过
ENTRYPOINT /usr/local/tomcat.sh start && tail -f /usr/local/apache-tomcat-8.0.50/logs/catalina.out
这个命令进行tomcat的启动,这样做是没有问题的。
现在将这块容易出现的问题进行总结,也就是当我们以daemon的形式运行一个容器的时候(这也是我们的前提),如果将Dockerfile的ENTRYPOINT命令进行一个修改成如下,及去掉后面的tail -f /usr/local/apache-tomcat-8.0.50/logs/catalina.out命令
ENTRYPOINT /usr/local/tomcat.sh start
我们会发现,容器启动后马上就退出了
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
477286652a54 ec2a "/usr/local/tomcat.s…" 6 seconds ago Exited (0) 5 seconds ago fsmp
为什么会启动后马上就退出了呢?????????????
补充:以daemon形式启动一个容器,即docker run -d参数的形式来运行一个容器时,-d选项介绍如下
-d, --detach Run container in background and print container ID
要找到退出的原因,就要了解CMD命令和ENTRYPOINT命令,在docker从入门到实践这本书中关于这两个命令的介绍,我们需要了解下,现将CMD的介绍引用过来
CMD 容器启动命令
CMD
指令的格式和 RUN
相似,也是两种格式:
shell
格式:CMD <命令>
exec
格式:CMD ["可执行文件", "参数1", "参数2"...](推荐)
- 参数列表格式:
CMD ["参数1", "参数2"...]
。在指定了ENTRYPOINT
指令后,用CMD
指定具体的参数。
之前介绍容器的时候曾经说过,Docker 不是虚拟机,容器就是进程。既然是进程,那么在启动容器的时候,需要指定所运行的程序及参数。CMD
指令就是用于指定默认的容器主进程的启动命令的。(主进程就是我们进入到启动的容器后查看进程编号为1的那个进程)
在运行时可以指定新的命令来替代镜像设置中的这个默认命令,比如,ubuntu
镜像默认的 CMD
是 /bin/bash
,如果我们直接 docker run -it ubuntu
的话,会直接进入 bash
。我们也可以在运行时指定运行别的命令,如 docker run -it ubuntu cat /etc/os-release
。这就是用 cat /etc/os-release
命令替换了默认的 /bin/bash
命令了,输出了系统版本信息。
在指令格式上,一般
推荐使用 exec
格式,这类格式在解析时会被解析为 JSON 数组,因此一定要使用双引号 "
,而不要使用单引号。
如果使用 shell
格式的话,实际的命令会被包装为 sh -c
的参数的形式进行执行。比如:
CMD echo $HOME
在实际执行中,会将其变更为:
CMD [ "sh", "-c", "echo $HOME" ]
这就是为什么我们可以使用环境变量的原因,因为这些环境变量会被 shell 进行解析处理。
提到 CMD
就不得不提容器中应用在前台执行和后台执行的问题。这是初学者常出现的一个混淆。
Docker 不是虚拟机,容器中的应用都应该以前台执行,而不是像虚拟机、物理机里面那样,用 systemd
去启动后台服务,容器内没有后台服务的概念。!!!!
一些初学者将 CMD
写为:
CMD service nginx start
然后发现容器执行后就立即退出了。甚至在容器内去使用 systemctl
命令结果却发现根本执行不了。这就是因为没有搞明白前台、后台的概念,没有区分容器和虚拟机的差异,依旧在以传统虚拟机的角度去理解容器。
对于容器而言,其启动程序就是容器应用进程,容器就是为了主进程而存在的,主进程退出,容器就失去了存在的意义,从而退出,其它辅助进程不是它需要关心的东西。
通过上面的介绍,我们应该知道上面那个问题的原因了,一句话:在Docker daemon模式下,无论你是使用ENTRYPOINT,还是CMD,最后的命令,一定要使当前进程也就是容器的主进程一直运行下去,这样才能够防容器退出,否则主进程退出了,容器就没有意义了,就会跟着退出。
下面一些也是无效的启动方式
CMD ["/usr/local/tomcat.sh","start"]
ENTRYPOINT ["/usr/local/tomcat.sh"]
CMD ["start"]
这样写也有效,但是前提是容器的环境中要有sshd这个终端服务器命令,关于sshd这个介绍我们在之后的博客中进行介绍
##SSH终端服务器作为后台运行
ENTRYPOINT /usr/local/tomcat.sh start && /usr/sbin/sshd -D
更多推荐
所有评论(0)