Docker:如何Dockerize和部署一个LAMP应用程序的多个实例

我需要部署许多相同LAMP(或LEMP)应用程序的实例:

  • 每个实例都可以从一个子域访问,前端负载均衡/代理
  • 每个实例必须有它自己的db数据和文件数据。
  • 每个实例都可能被监控
  • 内存限制/ CPU可能会设置每个应用程序实例
  • 容易自动部署新的webapp实例
  • 环境对于testing和开发可能是容易重现的。

申请要求:

  • PHPFPM进程( NginxMariaDBPHPFPM
  • 二进制文件( composerbower ,…)
  • 其他系统特定的库和configuration

在阅读Docker文档和许多howtos后,我看到了不同的解决scheme来dockerize这个Web应用程序:


解决scheme1:使用一体化容器

所有的堆栈都在一个容器中:

  • webapp源文件,EMP守护进程,二进制文件,…
  • mysql和webapp数据文件装载卷

例子 :

  • Tutum为Wordpress应用程序提供了一个全function的容器: https : //github.com/tutumcloud/tutum-docker-wordpress
  • Phusion为Docker提供了优化的基础镜像,精简了文档( https://github.com/phusion/baseimage-docker#docker_single_process ):

    Docker运行良好,容器中有多个进程。 事实上,没有技术上的原因,你应该限制自己的一个过程

优点 (恕我直言):

  • 似乎很容易自动部署,监视,摧毁…。
  • 易于使用prod,testing和开发环境。

缺点 (恕我直言):

  • 单片
  • 很难衡量
  • 不使用Docker的所有实力

解决scheme2:使用每个webapp实例的容器堆栈

对于要部署的每个Web应用程序,都会部署一个容器堆栈:

  • 每个进程一个容器: NginxMysqlPHP-FPM
  • 二进制容器( composerbower ,…)也可以docker化,也可以在phpfpm容器中合并
  • 装载mysql和webapp数据文件的卷

例子 :

  • OrdiStror工具Gaudi提供了一个基于3个“daemon”容器(nginx,mysql,phpfpm)和2个应用程序容器(composer,bower)的LEMP架构的示例( http://marmelab.com/blog/2014/06/ 04 / demo-symfony-with-docker-and-gaudi.html )

Pro (恕我直言):

  • 解耦
  • 每个实例进程隔离
  • 每个容器一个进程,不需要像RUnit或Supervisord那样的守护进程pipe理器

缺点 (恕我直言):

  • 看起来工作更复杂
  • 难以维护,看到所有容器状态,链接,版本的“大图”…

解决scheme3:混合前两种解决scheme

  • 一个“应用程序”容器与:app src文件,nginx,phpfmp,composer php,git ..
  • 一个用于db mysql的容器,可以与应用程序容器共享或不共享

我比Ops更开发,也对我感到困惑。

所以,问题:

  1. 在这些解决scheme之间进行select时, 需要考虑哪些标准,优缺点
  2. 如何select解决scheme2 来pipe理所有的容器堆栈 ,以获得所有容器状态,链接,版本的“全貌”。
  3. 应用程序的src文件(PHP)可能内置在容器中或作为卷挂载,例如。 / var / www?

我最近通过Docker分析了这种types的设置。 我知道有些人认为Docker是一种MicroVM,但是我认为Docker的理念更倾向于每个容器的单个进程。 这与编程中的单一责任原则相一致。 Docker容器越多,可重用性就越差,pipe理难度也越大。 我在这里发表了我所有的想法:

http://software.danielwatrous.com/a-review-of-docker/

然后,我使用Docker继续构buildLEMP堆栈。 在将PHP和Nginx进程拆分为独立的Docker容器方面,我没有发现什么价值,但Web和数据库函数位于不同的容器中。 我还展示了如何pipe理链接和卷共享以避免在容器中运行SSH守护进程。 你可以按照我在这里做的一个参考点。

http://software.danielwatrous.com/use-docker-to-build-a-lemp-stack-buildfile/

关于增加每个容器单个函数复杂性的观点,你是对的。 它看起来和感觉就像你有独特的分布层。 非常大的应用程序已经这么做了很多年,而且在通信,安全和pipe理方面确实增加了复杂性。 当然它也带来了一些好处。

两种解决scheme都是可能 不过,我会select解决scheme2 – 每个进程一个容器,因为它更符合Docker的“哲学”。

Docker的好处是,你可以用独立的构build块(单个应用程序的图像)创build一个应用程序堆栈(就像你的)。 您可以将这些构build块组合起来并重用它们。 如果你看看官方的Dockerregistry,你会发现大部分的组件是预生成的图像。 例如,您可以在https://registry.hub.docker.com/u/dockerfile/nginxfindNginx,并在https://registry.hub.docker.com/_/mysqlfindMySQL数据库。; 所以,如果你select每个进程/应用程序使用一个容器,设置你的堆栈变得非常容易:

(注意,这只是一个例子,我不熟悉PHP和东西…)

获取您的图片:

 docker pull mysql docker pull dockerfile/nginx docker pull tutum/apache-php docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=mysecretpassword -d mysql docker run -d -p 80:80 -v <sites-enabled-dir>:/etc/nginx/sites-enabled -v <log-dir>:/var/log/nginx dockerfile/nginx docker run -d -p 80:80 tutum/apache-php 

你可以像这样很容易地设置你的堆栈。 而且,如果你愿意的话,你可以改变一些单一的组件。 例如,您可以使用MariaDB更改MySQL数据库,而不用接触其他组件。

关于这个解决scheme最复杂的是如何configuration你的堆栈。 要链接您的容器,请查看https://docs.docker.com/userguide/dockerlinks 。 您可以使用这种方法来链接例如您的应用程序容器与您的MySQL容器。

Interesting Posts