Docker构建包含PHP多版本的LNMP环境(php53,56,72)

[Github项目地址]
https://github.com/copriwolf/docker-lnmp-with-mutli-php-versions

因为本人工作原因,经常需要使用到php5.3版本去维护一些旧系统,自然我就需要一个快速构建工具去支撑这个需求,所以也就有了这篇文章。

# 特性

  1. 一次部署多个php版本的服务。
  2. 所有配置文件,数据都储存在本地(非docker机内部)。
  3. MySQL数据库文件储存在本地(非docker机内部)。

# 快速部署

确定git, docker, docker-compose已经安装。

  1. 拉取项目到本地:

    1
    $ git clone https://github.com/copriwolf/docker-lnmp-with-mutli-php-versions.git
  2. 进入文件夹,并一键部署LNMP:

    1
    2
    $ cd docker-lnmp-with-mutli-php-versions
    $ docker-compose up
  3. 在浏览器中输入localhost,就可以到PHP7.2的phpInfo信息了

    php7.2的网站根目录在./site/site1


# 详细说明

## 国内Docker加速

国内的话,Docker是可以换用国内镜像仓库来加速镜像拉取速度。

  • [Docker中文官方] => https://www.docker-cn.com/registry-mirror
  • [淘宝的阿里云] => 有一个针对每一位用户的镜像加速器[登陆控制器-产品与服务-容器镜像服务-镜像加速器]

## 预览其他PHP版本?

  1. 可以添加一些hosts到系统里面。

    hosts文件地址:Linux & Mac 是在/etc/hosts, Windows是在C:\Windows\System32\drivers\etc.

    1
    2
    3
    127.0.0.1 www.site1.com
    127.0.0.1 www.site2.com
    127.0.0.1 www.site3.com
  2. 在浏览器中输入www.site2.com或者www.site3.com就能看到关于php56和php53的信息了。

## 创建一个php53/php56/php72网站?

本质上,我是用Nginx的配置文件去配置每一个网站的PHP版本的。
你去.conf/nginx/conf.d/site1.conf看一看,就会发现在fastcgi_pass这一参数是使用了fpm72:9000这个配置,表示使用fpm72这个容器的9000端口来处理nginx发过来的php请求。
所以,你如果想用php53/php56/php72,就对应的修改这个位置成fpm53:9000/fpm56:9000/fpm72:9000就可以了。

举个例子来生成一个php53网站:

  1. 复制一份site3.conf文件

    你想创建php56或者php72的网站的话,那就复制一份site2.conf或者site1.conf文件。

    1
    $ cp ./conf/nginx/conf.d/site3.conf ./conf/nginx/conf.d/youDomainName.conf
  2. 进去修改一下网站地址server_name,以及网站根目录 root

  3. 创建网站的根目录

    1
    $ mkdir ./site/youDomainName
  4. 把网页文件放入到目录

  5. 重启Docker-compose

    1
    $ docker-compose restart

## 架构图

事实上,docker暴露在外界的端口只有2个,一个是80端口供用户进行HTTP通信,另一个端口这是3306进行MYSQL通行。
而Nginx与PHP通信以及Mysql与PHP通信的接口都隐藏在docker内部。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
+- - - - - - - - - - - - - - - - - - - - - - - -+
' docker: '
' '
+------+ 80 ' +-------+ 9000 +-----------+ '
| | ------> ' | | <------> | PHP-FPM53 | <------+ '
| | ' | | +-----------+ | '
| | ' | | 9000 +-----------+ | '
| | ' | | <------> | PHP-FPM56 | <------+ '
| | ' | Nginx | +-----------+ | '
| User | ' | | 9000 +-----------+ | '
| | ' | | <------> | PHP-FPM72 | <------+ '
| | ' | | +-----------+ | '
| | ' | | | '
| | ' +-------+ | '
| | 3306 ' +-------+ 3306 | '
| | ------> ' | Mysql | <-----------------------------+ '
+------+ ' +-------+ '
' '
+- - - - - - - - - - - - - - - - - - - - - - - -+

## 目录结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
.
├── README.md
├── conf
│   ├── mysql
│   │   └── my.cnf mysql配置文件
│   ├── nginx
│   │   ├── conf.d
│   │   │   ├── site1.conf site1 配置文件
│   │   │   ├── site2.conf site2 配置文件
│   │   │   └── site3.conf site3 配置文件
│   │   └── nginx.conf nginx服务器配置文件
│   └── php
│   ├── php-fpm.d
│   │   └── www.conf php-fpm配置文件
│   └── php.ini php.ini配置文件
├── docker-compose.yml Docker构建文件
├── php
│   ├── php53
│   │   ├── Dockerfile php53构建文件
│   │   └── sources.list.jessie php53国内加速镜像配置
│   ├── php56
│   │   ├── Dockerfile php56构建文件
│   │   └── sources.list.jessie php56国内加速镜像配置
│   └── php72
│   ├── Dockerfile php72构建文件
│   └── sources.list.stretch php72国内加速镜像配置
├── site
│   ├── site1 site1 网站根目录
│   │   └── index.php
│   ├── site2 site2 网站根目录
│   │   └── index.php
│   └── site3 site3 网站根目录
│   └── index.php
└── src
└── SCREENSHOT.png github项目的截图

## Docker-Compose文件说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
nginx:
image: nginx:alpine
ports:
- "80:80"
# Ensure the read and write access
privileged: true
volumes:
- ./site/:/var/www/html/:rw
- ./conf/nginx/conf.d:/etc/nginx/conf.d/:ro
- ./conf/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- ./log/nginx/:/var/log/nginx/:rw
links:
- php53:fpm53
- php56:fpm56
- php72:fpm72
php53:
build: ./php/php53/
expose:
- "9000"
privileged: true
volumes:
- ./site/:/var/www/html:rw
- ./conf/php/php.ini:/usr/local/etc/php/php.ini:ro
- ./conf/php/php-fpm.d/www.conf:/usr/local/etc/php-fpm.d/www.conf:rw
- ./log/php-fpm/:/var/log/php-fpm/:rw
links:
- mysql:mysql
php56:
build: ./php/php56/
expose:
- "9000"
privileged: true
volumes:
- ./site/:/var/www/html/:rw
- ./conf/php/php.ini:/usr/local/etc/php/php.ini:ro
- ./conf/php/php-fpm.d/www.conf:/usr/local/etc/php-fpm.d/www.conf:rw
- ./log/php-fpm/:/var/log/php-fpm/:rw
links:
- mysql:mysql
php72:
build: ./php/php72/
expose:
- "9000"
privileged: true
volumes:
- ./site/:/var/www/html/:rw
- ./conf/php/php.ini:/usr/local/etc/php/php.ini:ro
- ./conf/php/php-fpm.d/www.conf:/usr/local/etc/php-fpm.d/www.conf:rw
- ./log/php-fpm/:/var/log/php-fpm/:rw
links:
- mysql:mysql
mysql:
image: mysql:latest
ports:
- "3306:3306"
privileged: true
volumes:
- ./conf/mysql/my.cnf:/etc/mysql/my.cnf:ro
- ./mysql/:/var/lib/mysql/:rw
- ./log/mysql/:/var/log/mysql/:rw
environment:
MYSQL_ROOT_PASSWORD: "1234567"

## 网站目录的读写权限

需要注意到compose文件中有一个参数privileged: true
这个参数的作用是使得container内的root拥有真正的root权限。否则,container内的root只是外部的一个普通用户权限。

## Nginx使用Alpine镜像

这是参考了yeszao/dnmp的设计,它的优势是:

  1. 用的是最新版nginx镜像,功能与nginx:latest一模一样
  2. alpine镜像用的是Alpine Linux内核,比ubuntu内核要小很多。

注意alpine的bash是 $ docker exec -it nginx /bin/sh,而不是一般的/bin/bash

## 网站目录挂载

对于每一个版本php容器来说,他的网站目录都是在当前容器的/var/www/html中。
要注意,php容器与nginx容器的网站目录一定要保持一致,才能让nginx路由给php的文件得到正确的解析。
而我则是在docker上都统一映射到宿主机的./site/目录下,具体是哪个网站加载哪个目录,
则是在./conf/nginx/conf.d/xxx.conf中配置了。

## MySQL调用

如果在docker里面运行mysql要填写mysql地址,请直接写mysql,因为我们在创建php-fpm容器时使用了命令--link mysql:mysql,等于把mysql容器链接过来,而且别名就叫做mysql,所以直接在mysql地址那里大胆填写mysql就可以调用了。

你可以类比,我们在新建网站时,在site1.conf中的fastcgi_pass填写fpm53是一样原理。
你可以看到docker-compose.yaml中nginx就是使用了link把php53以fpm53的别名链接进来的,所以我们在nginx容器内使用这个别名代指php53这个容器的IP地址。

## PHP的Dockerfile构建

因为php的构建较为繁琐,而且PHP53不能只能拉取PHP官方镜像(不再维护53版本),所针对PHP不同版本进行了Dockerfile构建,同时安装了一些常用的扩展。

## PHP安装更多扩展

  1. PHP56以及PHP73这2个都是拉去了官方PHP的映像,所以可以直接使用docker-php-ext-install命令进行扩展安装。记得安装完毕后,退出来需要重启这个docker容器才会生效

    1
    2
    3
    4
    # 进入php56的容器
    $ docker exec -it php56 /bin/bash/
    # 安装PDO扩展
    $ docker-php-ext-install pdo && docker-php-ext-install pdo_mysql && docker-php-ext-install mysqli
  2. PHP53因为官方PHP的映像不再维护,所以我们是构建了一个centos来兼容php53版本,所以安装扩展就是跟寻常linux安装php扩展是同样方法的。

# 致谢