Docker:如何Dockerize和部署一个LAMP应用程序的多个实例
我需要部署许多相同LAMP(或LEMP)应用程序的实例:
- 每个实例都可以从一个子域访问,前端负载均衡/代理
- 每个实例必须有它自己的db数据和文件数据。
- 每个实例都可能被监控
- 内存限制/ CPU可能会设置每个应用程序实例
- 容易自动部署新的webapp实例
- 环境对于testing和开发可能是容易重现的。
申请要求:
-
PHPFPM
进程(Nginx
,MariaDB
,PHPFPM
) - 二进制文件(
composer
,bower
,…) - 其他系统特定的库和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应用程序,都会部署一个容器堆栈:
- 每个进程一个容器:
Nginx
,Mysql
,PHP-FPM
, - 二进制容器(
composer
,bower
,…)也可以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更开发,也对我感到困惑。
所以,问题:
- 在这些解决scheme之间进行select时, 需要考虑哪些标准,优缺点 ?
- 如何select解决scheme2 来pipe理所有的容器堆栈 ,以获得所有容器状态,链接,版本的“全貌”。
- 应用程序的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容器。