Docker多个入口点

说我有以下的Dockerfile:

FROM ubuntu RUN apt-get update RUN apt-get install -y apache2 RUN apt-get install -y mongod #pretend this exists EXPOSE 80 ENTRYPOINT ["/usr/sbin/apache2"] 

ENTRYPOINT命令使得apache2在容器启动时启动。 我想也可以在命令service mongod start 。 然而,根据文档 , ENTRYPOINT中只能有一个入口点。 那么这样做的正确方法是什么呢?

正如Jared Markell所说,如果你想在docker集装箱中启动多个stream程,你必须使用主pipe 。 你将不得不configuration主pipe告诉他启动你的不同过程。

我在这篇博客文章中写到了这个,但是这里有一篇非常好的文章,详细介绍了在Docker中使用Supervisor的方式和原因。

基本上,你会想要做这样的事情:

 FROM ubuntu RUN apt-get update RUN apt-get install -y apache2 RUN apt-get install -y mongod #pretend this exists RUN apt-get install -y supervisor # Installing supervisord ADD supervisord.conf /etc/supervisor/conf.d/supervisord.conf EXPOSE 80 ENTRYPOINT ["/usr/bin/supervisord"] 

并添加一个configuration文件supervisord.conf

 [supervisord] nodaemon=true [program:mongodb] command=/etc/mongod/mongo #To adapt, I don't know how to launch your mongodb process [program:apache2] command=/usr/sbin/apache2 -DFOREGROUND 

编辑 :由于这个答案已经收到了相当多的upvotes,我想精确地作为一个警告,使用Supervisor 被认为是一个最好的做法来运行几个工作。 相反,您可能有兴趣为不同的stream程创build多个容器,并通过Docker组合来pipe理它们。 简而言之, Docker Compose允许您在一个文件中定义应用程序所需的所有容器,并在一个命令中启动它们。

我的解决scheme是将各个脚本放入/opt/run/并使用以下命令执行它们:

 #!/bin/bash LOG=/var/log/all touch $LOG for a in /opt/run/* do $a >> $LOG & done tail -f $LOG 

我的入口点就是这个脚本的位置,比如说它叫/opt/bin/run_all

 ADD 00_sshd /opt/run/ ADD 01_nginx /opt/run/ ADD run_all /opt/bin/ ENTRYPOINT ["/opt/bin/run_all"] 

简单的答案是,你不应该因为它打破了单一的责任原则:一个容器,一个服务。 想象一下,由于突然的工作量,您想要生成MongoDB的其他云图像 – 为什么还要以1:1的比例增加Apache2实例? 相反,你应该链接框,并让他们通过TCP说话。 有关更多信息,请参见https://docs.docker.com/userguide/dockerlinks/

我可以想到几种方法:

  • 你可以编写一个脚本来放置容器( ADD ),执行所有的启动命令,然后把它放在ENTRYPOINT
  • 我想你可以把任何shell命令放在ENTRYPOINT ,这样你就可以执行service mongod start && /usr/sbin/apache2

我无法获得&&的使用情况。 我能够解决这个在这里描述: https : //stackoverflow.com/a/19872810/2971199

所以在你的情况下,你可以这样做:

 RUN echo "/usr/sbin/apache2" >> /etc/bash.bashrc RUN echo "/path/to/mongodb" >> /etc/bash.bashrc ENTRYPOINT ["/bin/bash"] 

您可能需要/想要编辑您的启动命令。

如果你多次运行你的Dockerfile,要小心,你可能不希望命令的多个副本附加到你的bash.bashrc文件中。 你可以使用grepif语句使你的RUN命令是幂等的。

您不能在Dockerfile中指定多个入口点。 要在同一个Docker容器中运行多个服务器,您必须使用能够启动服务器的命令。 Supervisord已经被引用,但我也可以推荐multirun这是一个更轻的select。