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
文件中。 你可以使用grep
和if
语句使你的RUN
命令是幂等的。
您不能在Dockerfile中指定多个入口点。 要在同一个Docker容器中运行多个服务器,您必须使用能够启动服务器的命令。 Supervisord已经被引用,但我也可以推荐multirun这是一个更轻的select。