从部署旨在在台式机上的用户上运行的应用程序的角度来看,我正在努力将自己的头全放在Docker上。我的应用程序只是一个Flask Web应用程序和mongo数据库。通常,我将同时安装在VM中,并将主机端口转发到来宾Web应用程序。我想尝试一下Docker,但不确定使用多个程序的含义。文档说只能有ENTRYPOINT,所以我如何拥有Mongo和我的flask应用程序。还是需要将它们放在单独的容器中,在这种情况下它们如何彼此通信,这如何使应用程序的分发变得容易?
从部署旨在在台式机上的用户上运行的应用程序的角度来看,我正在努力将自己的头全放在Docker上。我的应用程序只是一个Flask Web应用程序和mongo数据库。通常,我将同时安装在VM中,并将主机端口转发到来宾Web应用程序。我想尝试一下Docker,但不确定使用多个程序的含义。文档说只能有ENTRYPOINT,所以我如何拥有Mongo和我的flask应用程序。还是需要将它们放在单独的容器中,在这种情况下它们如何彼此通信,这如何使应用程序的分发变得容易?
Answers:
只能有一个ENTRYPOINT,但是该目标通常是一个脚本,该脚本启动所需的许多程序。您还可以使用例如Supervisord或类似工具来在单个容器内启动多个服务。这是一个在单个容器中运行mysql,apache和wordpress的docker容器的示例。
假设您有一个供单个Web应用程序使用的数据库。然后,在单个容器中同时运行它们可能会更容易。
如果您有一个共享数据库供多个应用程序使用,则最好在其自己的容器中运行数据库,而每个应用程序都在各自的容器中运行。
当应用程序在不同的容器中运行时,它们至少有两种相互通信的可能性:
我对运行LAMP堆栈,Mongo DB和我自己的服务有类似的要求
Docker是基于OS的虚拟化,这就是为什么它在一个正在运行的进程中隔离其容器,因此它需要至少一个在FOREGROUND中运行的进程。
因此,您提供自己的启动脚本作为入口点,因此您的启动脚本成为扩展的Docker映像脚本,您可以在其中堆叠任何数量的服务,直到启动至少一项综合服务为止。
因此,我的Docker映像文件最后有两行:
COPY myStartupScript.sh /usr/local/myscripts/myStartupScript.sh
CMD ["/bin/bash", "/usr/local/myscripts/myStartupScript.sh"]
在我的脚本中,我运行所有MySQL,MongoDB,Tomcat等。最后,我将Apache作为前台线程运行。
source /etc/apache2/envvars
/usr/sbin/apache2 -DFOREGROUND
这使我能够启动所有服务,并使容器保持活动状态,而最后一个服务开始处于前台
希望能帮助到你
UPDATE:自从我上次回答了这个问题,新的东西都拿出了像泊坞撰写,它可以帮助你在自己的容器中运行的每一项服务,但绑定所有的人都在一起,这些服务之间的依赖关系,试图更多地了解泊坞窗,撰写和使用它,除非您的需求不符合它,否则它是一种更优雅的方法。
我强烈不同意以前的一些建议在同一容器中运行两个服务的解决方案。文档中明确指出,不建议这样做:
通常建议您通过每个容器使用一项服务来分离关注区域。该服务可以派生到多个进程中(例如,Apache Web服务器启动多个工作进程)。可以有多个进程,但是要从Docker中获得最大收益,请避免一个容器负责整个应用程序的多个方面。您可以使用用户定义的网络和共享卷连接多个容器。
有监督程序或类似程序的良好用例,但运行Web应用程序+数据库不属于其中。
您绝对应该使用docker-compose做到这一点,并编排具有不同职责的多个容器。
它们可以放在单独的容器中,实际上,如果应用程序也打算在更大的环境中运行,则可能会存在。
多容器系统将需要一些更多的业务流程,以便能够调出所有必需的依赖,但在泊坞v0.6.5 +,有一个新的设施与内置泊坞窗本身的帮助- 链接。对于多机解决方案,它仍然需要从Docker环境外部进行安排。
使用两个不同的容器,这两个部分仍通过TCP / IP进行通信,但是除非端口被专门锁定(不建议这样做,否则您将无法运行多个副本),则必须传递新端口数据库已经针对应用程序公开,因此它可以与Mongo通信。再次,链接可以提供帮助。
对于更简单的小型安装,其中所有依赖项都在同一个容器中进行,还可以通过最初称为ENTRYPOINT的程序来启动数据库和Python运行时。这可以简单的shell脚本,或其他一些过程控制器- Supervisord颇为流行,以及一些例子公共Dockerfiles存在。
Docker提供了一些有关如何执行此操作的示例。轻量级的选项是:
将所有命令放入包装器脚本中,其中包含测试和调试信息。以您的身份运行包装脚本
CMD
。这是一个非常幼稚的例子。首先,包装脚本:
#!/bin/bash
# Start the first process
./my_first_process -D
status=$?
if [ $status -ne 0 ]; then
echo "Failed to start my_first_process: $status"
exit $status
fi
# Start the second process
./my_second_process -D
status=$?
if [ $status -ne 0 ]; then
echo "Failed to start my_second_process: $status"
exit $status
fi
# Naive check runs checks once a minute to see if either of the processes exited.
# This illustrates part of the heavy lifting you need to do if you want to run
# more than one service in a container. The container will exit with an error
# if it detects that either of the processes has exited.
# Otherwise it will loop forever, waking up every 60 seconds
while /bin/true; do
ps aux |grep my_first_process |grep -q -v grep
PROCESS_1_STATUS=$?
ps aux |grep my_second_process |grep -q -v grep
PROCESS_2_STATUS=$?
# If the greps above find anything, they will exit with 0 status
# If they are not both 0, then something is wrong
if [ $PROCESS_1_STATUS -ne 0 -o $PROCESS_2_STATUS -ne 0 ]; then
echo "One of the processes has already exited."
exit -1
fi
sleep 60
done
接下来,Dockerfile:
FROM ubuntu:latest
COPY my_first_process my_first_process
COPY my_second_process my_second_process
COPY my_wrapper_script.sh my_wrapper_script.sh
CMD ./my_wrapper_script.sh