Docker作为一项最流行的虚拟化技术,从2013年发展至今,已经发展的如火如荼。Docker 使用 Google 公司推出的 Go 语言 进行开发实现,基于 Linux 内核的 cgroup,namespace,以及 AUFS 类的 Union FS 等技术,对进程进行封装隔离,属于 操作系统层面的虚拟化技术。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。

Docker和Vagrant

docker-vm

docker-lxc

Docker 与我之前尝试的 用Vagrant搭建跨平台ubuntu开发环境 最大的不同的是,Docker容器是运行于操作系统层上,它是轻量级的,而vagrant属于虚拟机管理工具,依赖 virtualbox/vmware/hyper-v 等,在建立多个示例上和分布式微服务系统架构,比如云服务平台下,Docker无疑更节省资源切便捷。

Docker化PHP

最近几天心血来潮,趁着有时间研究了下Docker,决定动手搭建一个基于Docker搭建的PHP环境。

准备

首先我们需要确定的几个需求:

安装

为了方便快速搭建docker环境,我准备了一个脚本,以ubuntu16.04为基础:

#!/bin/bash
# ubuntu中文源
sed -i 's/archive.ubuntu.com/mirrors.163.com/g' /etc/apt/sources.list
sed -i 's/security.ubuntu.com/mirrors.163.com/g' /etc/apt/sources.list
sudo apt update && sudo apt upgrade -y
sudo apt autoremove -y
# 修改时区
sudo cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
echo Asia/Shanghai | sudo tee /etc/timezone
sudo apt install zsh lrzsz screenfetch curl -y
# 配置zsh 安装当前用户 所以不加sudo
sh -c "$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"
chsh -s $(which zsh)
# 安装docker docker-compose
curl -fsSL get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker ubuntu
# 配置docker国内mirror,可以使用Daocloud、灵雀云等镜像加速服务
curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://xxxxxx.m.daocloud.io
sudo service docker restart
sudo curl -L https://github.com/docker/compose/releases/download/1.18.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

镜像

Nginxmongo可以直接使用dockerhub镜像仓库上开箱即用的镜像,比如:

$ docker run --rm -p 80:80 --name php-nginx -d nginx:1.12.2-alpine

到了PHP这里,需要满足自己的需求,可以使用 dockerfile 文件构建自己的镜像,这里我使用基于官方php:fpm镜像,额外安装想要的扩展。

FROM php:fpm

LABEL maintainer="opso <945206413@qq.com>"

ENV TIMEZONE Asia/Shanghai
ENV SWOOLE_VERSION 4.0.3

# replace sources.list
RUN sed -i 's/deb.debian.org/mirrors.163.com/g' /etc/apt/sources.list \
    && sed -i 's/security.debian.org/mirrors.163.com/g' /etc/apt/sources.list \
    && cp /usr/share/zoneinfo/${TIMEZONE} /etc/localtime \
    && echo "${TIMEZONE}" > /etc/timezone

# init
RUN apt-get update && \
    apt-get install -y --no-install-recommends \
    curl \
    wget \
    zip \
    git \
    unzip \
    procps \
    libz-dev \
    libpq-dev \
    libjpeg-dev \
    libpng-dev \
    libfreetype6-dev \
    libssl-dev \
    libmcrypt-dev \
    libmemcached-dev \
    apt-utils \
    && rm -rf /var/lib/apt/lists/*

# install hiredis
RUN wget https://github.com/redis/hiredis/archive/v0.13.3.tar.gz -O hiredis.tar.gz \
    && mkdir -p hiredis \
    && tar -xf hiredis.tar.gz -C hiredis --strip-components=1 \
    && rm hiredis.tar.gz \
    && ( \
        cd hiredis \
        && make -j$(nproc) \
        && make install \
        && ldconfig \
    ) \
    && rm -r hiredis

# install php extentions
RUN pecl channel-update pecl.php.net \
    && docker-php-ext-configure gd \
    --enable-gd-native-ttf \
    --with-jpeg-dir=/usr/lib \
    --with-freetype-dir=/usr/include/freetype2 \
    && docker-php-ext-install -j$(nproc) bcmath mysqli pdo_mysql gd \
    && pecl install mongodb \
    && docker-php-ext-enable mongodb \
    && pecl install memcached \
    && docker-php-ext-enable memcached \
    && pecl install redis \
    && docker-php-ext-enable redis \
    && pecl clear-cache

# install swoole extention
RUN wget https://github.com/swoole/swoole-src/archive/v${SWOOLE_VERSION}.tar.gz -O swoole.tar.gz \
    && mkdir -p swoole \
    && tar -xf swoole.tar.gz -C swoole --strip-components=1 \
    && rm swoole.tar.gz \
    && ( \
        cd swoole \
        && phpize \
        && ./configure --enable-async-redis --enable-mysqlnd --enable-coroutine --enable-openssl \
        && make -j$(nproc) \
        && make install \
    ) \
    && rm -r swoole \
    && docker-php-ext-enable swoole

# install composer
RUN curl -sS https://install.phpcomposer.com/installer | php \
    && mv composer.phar /usr/local/bin/composer \
    && composer config -g repositories.packagist composer https://packagist.phpcomposer.com \
    && composer self-update --clean-backups

EXPOSE 9000
CMD ["php-fpm"]

docker-compose

为了方便将nginxphpmongo 环境组成一个集群,便于管理和文件共享,这里推荐使用docker-compose工具,配置也只需一个文件: docker-compose.yaml

# 注意这里的vertion是docker-compose yaml格式的version 不同的version支持不同的语法
version: '3'
services:
    nginx:
        # 依赖关系 先跑php
        depends_on:
            - "php"
        image: "nginx:1.12.2-alpine"
        # 数据卷
        volumes:
            - "$PWD/conf.d:/etc/nginx/conf.d"
            - "$PWD/www:/usr/share/nginx/html"
        # 端口映射
        ports:
            - "80:80"
        # 容器名称
        container_name: "compose-nginx"
    php:
        build: php/
        volumes:
            - "$PWD/www:/var/www/html"
        container_name: "compose-php"
    mongo:
        image: "mongo:3.4.11"
        volumes: 
            - "/data/mongodb:/data/db"
        ports: 
            - "27017:27017"
        container_name: "compose-mongo"

在命令行下运行:

$ docker-compose build
$ docker-compose up -d

由于我的是在vagrant虚拟机上安装的docker环境,然后就可以去局域网上看到phpinfo了~

代码我已经提交到我的github上了:opso-code/docker-php

参考资料

Docker——从入门到实践

Docker化PHP环境

Docker 实践(八):构建 Laravel 开发环境