一、问题

我们可以在一个容器中运行应用程序的所有服务,以运行wordpress为例,你想知道一个容器中同时运行MySQL和HTTPD服务。由于Docker运行的是前台进程,所以你需要找到一种运行多个“前台”进程的方式
这种方法有很多,最简单的就是把多个启动命令放到一个启动脚本里面,启动的时候直接启动这个脚本,另外就是安装进程管理工具

二、解决方案

本节我们将使用进程管理工具supervisor来管理容器中的多个进程。使用supervision可以更好的控制、管理重启我们希望运行的进程。
首先下载本书的示例GitHub示例这些文件包含启动虚拟机Vagrantfile,Docker运行在虚拟机中还包含一个Dockerfile来定义要创建的镜像,此外还有一个supervisor的配置文件和一个WordPress的配置文件
Dockerfile:

  1. FROM ubuntu:14.04
  2. RUN apt-get update && apt-get -y install \
  3. apache2 \
  4. php5 \
  5. FROM ubuntu:14.04
  6. RUN apt-get update && apt-get -y install \
  7. apache2 \
  8. php5 \
  9. php5-mysql \
  10. supervisor \
  11. wget
  12. RUN echo 'mysql-server mysql-server/root_password password root' | debconf-set-selections && \
  13. echo 'mysql-server mysql-server/root_password_again password root' | debconf-set-selections
  14. RUN apt-get install -qqy mysql-server
  15. RUN wget http://wordpress.org/latest.tar.gz && \
  16. tar xzvf latest.tar.gz && \
  17. cp -R ./wordpress/* /var/www/html && \
  18. rm /var/www/html/index.html
  19. RUN (/usr/bin/mysqld_safe &); sleep 5; mysqladmin -u root -proot create wordpress
  20. COPY wp-config.php /var/www/html/wp-config.php

Vgrantfile:

  1. # -*- mode: ruby -*-
  2. # vi: set ft=ruby :
  3. # Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
  4. VAGRANTFILE_API_VERSION = "2"
  5. Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  6. # Every Vagrant virtual environment requires a box to build off of.
  7. config.vm.box = "ubuntu/trusty64"
  8. # Create a forwarded port mapping which allows access to a specific port
  9. # within the machine from a port on the host machine. In the example below,
  10. # accessing "localhost:8080" will access port 80 on the guest machine.
  11. # config.vm.network "forwarded_port", guest: 80, host: 8080
  12. # Create a private network, which allows host-only access to the machine
  13. # using a specific IP.
  14. config.vm.network "private_network", ip: "192.168.33.10"
  15. config.vm.provider "virtualbox" do |vb|
  16. vb.customize ["modifyvm", :id, "--memory", "2048"]
  17. end
  1. [supervisord]
  2. nodaemon=true
  3. [program:mysqld]
  4. command=/usr/bin/mysqld_safe
  5. autostart=true
  6. autorestart=true
  7. user=root
  8. [program:httpd]
  9. command=/bin/bash -c "rm -rf /run/httpd/* && /usr/sbin/apachectl -D FOREGROUND"

这里定义了两个被监控和运行的服务:mysqld和httpd每个程序都可以使用诸如autorestart和autostart等选项。最重要的指令是command,其定义了如何运行每个程序。
在docker主机上构建该镜像并且启动一个后台程序如果使用了Vagrant的虚拟机,可以执行如下命令。

  1. $ cd /vagrant
  2. $ docker build -t wordpress .
  3. $ docker run -d -p 80:80 wordpress

因为我没有使用Vagrant的方式所以我就不进行测试了,当容器运行起来以后,游览器中打开http://,就可以进入到WordPress的配置页面了

三、讨论

尽管通过supervisor在一个容器中运行多个应用服务看起来很完美但是,最好还是使用多个容器来运行不同的服务。这能充分利用容器的隔离优势,也能帮助你创建基于微服务设计思想的应用。最终这也将会使你的应用更具有弹性和拓展性。