我可以在Docker容器中运行多个程序吗?

时间:2013-11-13 07:44:40

标签: docker

我正试图从部署一个旨在在桌面上运行的应用程序的角度来绕过Docker。我的应用程序只是一个烧瓶Web应用程序和mongo数据库。通常我会在VM中安装它们,并将主机端口转发到来宾Web应用程序。我想尝试一下Docker,但我不确定我打算如何使用多个程序。文件说只有ENTRYPOINT,所以我怎么能有Mongo和我的烧瓶申请。或者他们需要在单独的包含中,在这种情况下,他们如何相互交谈以及如何使分发应用程序变得容易?

8 个答案:

答案 0 :(得分:104)

只能有一个ENTRYPOINT,但该目标通常是一个可以启动所需程序的脚本。您还可以使用例如Supervisord或类似的方法来处理在单个容器内启动多个服务。 This is an example of a docker container running mysql, apache and wordpress within a single container

说,您有一个由单个Web应用程序使用的数据库。然后,在单个容器中运行它们可能更容易。

如果您有一个由多个应用程序使用的共享数据库,那么最好在自己的容器中运行数据库,并将每个应用程序放在各自的容器中。

当应用程序在不同的容器中运行时,应用程序如何相互通信至少有两种可能性:

  1. 使用公开的IP端口并通过它们进行连接。
  2. 最近的泊坞广告版本support linking

答案 1 :(得分:19)

我有类似的要求运行LAMP堆栈,Mongo DB和我自己的服务

Docker是基于操作系统的虚拟化,这就是为什么它围绕正在运行的进程隔离其容器的原因,因此它需要在FOREGROUND中运行至少一个进程。

因此,您提供自己的启动脚本作为入口点,因此您的启动脚本将成为扩展的Docker镜像脚本,您可以在其中堆叠任意数量的服务,直到至少一个FOREGROUND SERVICE启动,太过分了

所以我的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

这使我能够启动所有服务,并使容器保持活动状态,最后一个服务开始位于前台

希望有所帮助

更新:自从我上次回答这个问题以来,新的事情就像Docker compose一样,它可以帮助您在自己的容器上运行每个服务,但将所有服务绑定在一起这些服务之间存在依赖关系,尝试了解docker-compose的更多内容并使用它,除非您的需求与之匹配,否则它会更优雅。

答案 2 :(得分:5)

它们可以位于不同的容器中,实际上,如果应用程序也打算在更大的环境中运行,它们可能就是这样。

多容器系统需要更多的业务流程来提供所有必需的依赖项,但在Docker v0.6.5 +中,有一个新的工具可以帮助构建Docker本身 - {{3} }。使用多机解决方案,它仍然需要从Docker环境外部进行排列。

使用两个不同的容器,这两个部分仍然通过TCP / IP进行通信,但除非端口已被特定锁定(不推荐,因为您无法运行多个副本),否则您必须通过数据库已针对应用程序公开的新端口,以便它可以与Mongo通信。这也是Linking可以提供帮助的东西。

对于一个更简单的小型安装,其中所有依赖项都在同一个容器中,同时也可以通过最初被称为ENTRYPOINT的程序启动数据库和Python运行时。这可以像shell脚本一样简单,或者其他一些进程控制器 - Linking非常流行,并且公共Dockerfiles中存在许多示例。

答案 3 :(得分:3)

我同意其他答案,使用两个容器是可取的,但如果你的心脏设置在一个容器中提供多个服务,你可以使用像supervisord这样的东西。

例如,在Hipache中,包含的Dockerfile运行supervisord,而supervisord.conf文件指定运行hipache和redis-server。

答案 4 :(得分:1)

Docker提供了couple of examples如何做到这一点。轻量级选项是:

  

将所有命令放在包装器脚本中,并完成测试   和调试信息。将包装脚本作为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

答案 5 :(得分:0)

我强烈不同意之前建议在同一容器中运行这两种服务的一些解决方案。 It's clearly stated in the documentation that it's not a recommended

  

通常建议您通过每个容器使用一个服务来区分关注的区域。该服务可能分为多个进程(例如,Apache Web服务器启动多个工作进程)。拥有多个进程是可以的,但要从Docker中获得最大的好处,请避免一个容器负责整个应用程序的多个方面。您可以使用用户定义的网络和共享卷连接多个容器。

对于supervisord或类似程序有很好的用例,但运行Web应用程序+数据库不是它们的一部分。

您绝对应该使用docker-compose来执行此操作并协调具有不同职责的多个容器。

答案 6 :(得分:0)

您可以使用wait在前台运行2个进程。只需制作一个包含以下内容的bash脚本即可。例如start.sh

# runs 2 commands simultaneously:

mongod & # your first application
P1=$!
python script.py & # your second application
P2=$!
wait $P1 $P2

在您的Dockerfile中,使用

启动它
CMD bash start.sh

答案 7 :(得分:0)

如果专用脚本似乎开销太大,则可以使用sh -c显式生成单独的进程。例如:

CMD sh -c 'mini_httpd -C /my/config -D &' \
 && ./content_computing_loop