一直对Docker有所耳闻,但是听到“虚拟化”这个名词又让我有点望而却步。
受公司里几个技术大牛的影响才开始渐渐去了解,了解之后发现真的很好用。

这篇文章略过Docker以及虚拟化的基础知识,着重在实践方面演示一遍怎么用Docker去搭建一个LNMP环境。

前言

Docker和以往的比如KVM呀Openvz呀之类的虚拟技术不同,不是在硬件层面的虚拟化,而是OS层面的虚拟化。
一个容器就是一个进程,所以Docker非常的轻量。
笔者在开始试着用Docker搭建LNMP环境时进入了一个误区,将Nginx,PHP和MariaDB全都打包在一直镜像里。
这种做法是错误的,有点Anti-Pattern的感觉。

MariaDB

因为Nginx和PHP之间的配置有些复杂,先从简单的MariaDB开始讲。
启动MariaDB只需要一条命令:

$ docker run --name mariadb -d -v /usr/local/mariadb/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 mariadb

PHP

PHP默认没有gd、mbstring之类的扩展,需要Dockerfile自己再编译一遍。
下面是自用的一个Dockerfile示例,具体可以根据需求自行修改:

FROM php:fpm
RUN apt-get update && apt-get install -y \
        libfreetype6-dev \
        libjpeg62-turbo-dev \
        libmcrypt-dev \
        libpng12-dev \
    && docker-php-ext-install -j$(nproc) iconv mcrypt opcache mbstring mysqli pdo_mysql\
    && docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
    && docker-php-ext-install -j$(nproc) gd

建好Dockerfile之后可以用docker build . -t php:custom来编译它。
启动的命令也可以根据自身需求修改。假如网站的根目录是/home/wwwroot,php.ini在/etc/docker下,我们可以这样写启动命令:
php.ini可以去php官网下载完整包自己提取出来。

$ docker run --name php-fpm -d -v /home/wwwroot:/home/wwwroot -v /etc/docker/php.ini:/usr/local/php/etc/php.ini --link mariadb:mariadb

Nginx

启动nginx也非常简单,假如网站的根目录是/home/wwwroot,nginx.conf在/etc/docker下:

$ docker run --name nginx -d -v /home/wwwroot:/home/wwwroot -v /etc/docker/nginx.conf:/etc/nginx/nginx.conf -p 80:80 -p 443:443 --link php:php-fpm

以下是一个nginx.conf范例(只保留server段),你也可以启动一个nginx容器之后docker cp nginx:/etc/nginx/nginx.conf /etc/docker/nginx.conf拷贝出来

server {
    listen 80;
    server_name localhost;
    root /home/wwwroot;
    location / {
        index index.php index.html index.htm;
    }
    location ~* \.php$ {
        fastcgi_index index.php;
        fastcgi_pass php:9000;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param SCRIPT_NAME $fastcgi_script_name;
    }
}

Docker-Compose

像上面这样一步一步地配置是不是很麻烦?我们可以用docker-compose一步到位。
以下是一个docker-compose.yml的范例:

version: '2'

services:
  nginx:
    image: nginx
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /home/wwwroot:/home/wwwroot
      - /etc/docker/nginx.conf:/etc/nginx/nginx.conf
    links:
      - php-fpm:php

  php-fpm:
    build: .
    image: php:custom
    volumes:
      - /home/wwwroot:/home/wwwroot
      - /etc/docker/php.ini:/usr/local/php/etc/php.ini
    links:
      - mariadb:mariadb

  mariadb:
    image: mariadb
    volumes:
      - /usr/local/mariadb/data:/var/lib/mysql
    environment:
      - "MYSQL_ROOT_PASSWORD=123456"

然后使用docker-compose up -d来启动所有的程序。
整个过程不到10分钟,是不是比自己编译一两个小时要好多了呢。

后记

笔者最近为了试用BBR,将自己的独立服务器升级到4.9kernel(Ubuntu 16.04),发现Docker不能安装了。会卡在Setting up docker..好长时间没有动静。
折腾好久发现原因是apt-get install linux-image-extra-$(uname -r)不成功,找不到相应的安装包。
docker会一直去试着使用aufs驱动,就会发生卡住的情况。
我们可以先杀掉apt-get进程,然后停止docker服务。在/etc/docker/daemon.json里进行这样的配置:

{
    "storage-driver": "overlay"
}

然后重新安装一次应该就可以了。
以下几条命令可能会对你有用。

$ ps ax|grep apt-get 查看apt-get的进程号
$ kill -9 (apt-get PID) 杀掉apt-get进程
$ systemctl stop docker
最后修改:2017 年 01 月 04 日
如果觉得我的文章对你有用,请随意赞赏