Docker搭建nginx php mysql环境

0x00 准备工作

下载所需要的镜像,推荐注册daocloud,配置下可以加速下载Docker Hub上的镜像。

1
2
3
dao pull nginx:1.8
dao pull php:5.6.19-fpm
dao pull mysql:5.5.48

下载完后,sudo docker images

1
2
3
4
REPOSITORY                              TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
mysql 5.5.48 2805299e41bf 3 days ago 256.3 MB
php 5.6.19-fpm c6cc8696a7cb 2 weeks ago 452.9 MB
nginx 1.8 866d2654a320 4 weeks ago 133.3 MB

0x01 Mysql容器配置

首先,我们先看看Mysql镜像官方给的使用方法。看官方文档,是必须的步骤

  • 运行Mysql容器:

Starting a MySQL instance is simple:

1
$ docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag

上面的docker命令可以后台启动一个Mysql容器,并且设置root密码为my-secret-pw-e表示设置环境变量。-d表示后台运行。

  • 进入容器执行shell和查看Mysql日志

Container shell access and viewing MySQL logs

1
2
3
$ docker exec -it some-mysql bash

$ docker logs some-mysql

很有用的exec命令:当容器启动后,可以随时使用exec命令进入容器执行命令。
这里执行的bash命令,会有产生一个终端操作。
-t 选项让Docker分配一个伪终端(pseudo-tty)并绑定到容器的标准输入上。
-i 则让容器的标准输入保持打开。

  • 存储数据位置:

Start your mysql container like this:

1
$ docker run --name some-mysql -v /my/own/datadir:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag

容器中,数据库的数据是存放在容器的/var/lib/mysql目录下,这里使用本地/my/own/datadir目录挂载到目标目录。这样,数据库的数据都存储在本地了。 -v即将一个本地目录挂载到容器中,十分方便。 说明:

  • 挂载的本地目录和容器目录。里面的文件可以随时实时更新,就像操作一个本地文件一样。可以看作为容器和本地共享的磁盘。

  • 新建并启动容器

于是,我们有了这样的运行一个容器命令:

1
docker run --name mysql_db -e MYSQL_ROOT_PASSWORD=password -v /my/own/datadir:/var/lib/mysql -d mysql:5.5.48

容器名字为mysql_db,使用的镜像为mysql:5.5.48

1
docker ps -a

使用该命令可以查看所有存在的docker容器。都有标示其是否正在运行,或者已停止。需要用的时候,还可以使用start命令重新启动。当然,stop命令可以停止容器运行。

0x02 php-fpm容器配置

  • 安装phpmysql扩展问题

对于php-fpm默认没有安装mysql模块,所以使用mysql_connect函数时,会报无法识别的错误。 利用刚学到的一招,进入php-fpm容器:

1
sudo docker exec -it phpfpm bash

可以这样查看php模块:

1
php -m 查看安装模块

可以查看phpinfo信息:

1
2
php -i | grep "Loaded Configuration File" 
php -i | grep "php.ini"
  • 解决方案

这个问题困扰了很久,查了很多如何安装mysql模块的问题。
最终遇到问题,一样的步骤,看官方文档的使用说明,找到了解决方案: 安装php核心扩展:
PHP Core Extensions

1
2
3
4
5
6
7
8
9
FROM php:5-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 \
&& docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
&& docker-php-ext-install -j$(nproc) gd

官方说明中,给出了以上的Dockerfile文件,可以安装新的核心模块。这里顺便学习了下Dockerfile的用法,发现很好用。 Dockerfile可以使我们可以根据已有镜像创建一个新的镜像。命令格式也很好理解,具体参考Docker —— 从入门到实践这本书。 关于phpfpm中mysqlnd模块也是蛮有意思的,可以方便我们调用连接mysql,只需编译的时候加上:

1
2
3
--with-mysql=mysqlnd  \
--with-mysqli=mysqlnd \
--with-pdo-mysql=mysqlnd

而这个也可以使用phpize后面动态安装这些扩展。
另外,看一下官方的Dokerfile会了解更多:https://github.com/docker-library/php/blob/4677ca134fe48d20c820a19becb99198824d78e3/5.6/fpm/Dockerfile

  • 利用Dockerfile安装mysql模块

于是,我参考了网上关于安装php模块的知识,有了以下的Dockerfile创建了新的镜像phpfpm:with_mysql: Dockerfile:

1
2
3
4
5
6
7
8
9
10
FROM php:5.6.19-fpm
# Install modules
RUN docker-php-ext-configure mysql --with-mysql=mysqlnd \
&& docker-php-ext-install mysql \
&& docker-php-ext-configure mysqli --with-mysqli=mysqlnd \
&& docker-php-ext-install mysqli \
&& docker-php-ext-configure pdo_mysql --with-pdo-mysql=mysqlnd \
&& docker-php-ext-install pdo_mysql

CMD ["php-fpm"]

执行命令:

1
docker build -t phpfpm:with_mysql Dockerfile所在目录

即可构建新的带有mysql模块的镜像。
实际上,从输出的信息可以看出:它内部还是使用了phpize来安装mysqlmysqlipdo_mysql这三个模块。

  • 与db进行连接

这里使用到了docker的容器互联技术,使用--link 容器名:别名可以方便的将容器间互联,进行信息交互。
于是有了如下运行命令:

1
docker run -d -v 本地目录/webcode:/webcode --name phpfpm_db --link mysql_db:mysql_db php:5.6.19-fpm

进入容器,cat /etc/hosts可以看到:

1
192.168.0.2     mysql_db

这里还挂载了一个代码目录到容器中,方便进行测试。

  • 测试连接

进入容器,新建测试数据库和表:

1
2
3
4
5
6
7
8
9
10
11
12
sudo docker exec -it mysql_db bash

mysql> create database test_db;

mysql> create table IF NOT EXISTS student( name VARCHAR(20), sex INT(11) );
mysql> alter table student change sex name INT(10);
mysql> select * from student;
+------+------+
| name | age |
+------+------+
| jack | 11 |
+------+------+

进入phpfpm_db容器,测试: test_db.php:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$con = mysql_connect("mysql_db","root","password");
if (!$con)
{
die('Could not connect: ' . mysql_error());
}

// some code

mysql_select_db("test_db", $con);
$result = mysql_query("SELECT * FROM student");

while($row = mysql_fetch_array($result))
{
echo $row['name'] . " " . $row['age'];
echo "<br />";
}
mysql_close($con);
?>

运行测试:

1
2
3
4
cd /webcode/
php test_db.php

jack 11<br />

0x03 nginx容器配置

跟上面配置一样,直接看运行容器命令:

1
sudo docker run --name nginx_php_server -d -p 80:80 --link phpfpm_db:phpfpm_db  -v 本地目录/conf/default.conf:/etc/nginx/conf.d/default.conf  --volumes-from  phpfpm_5.6.19 nginx:1.8

--volumes-from命令是将phpfpm_db中挂载的文件,同样挂载在nginx_php_server中。即,webcode目录同样存在nginx_php_server容器的/webcode目录中。 -p使主机的80端口映射到容器上。 主要来看nginx的使用:

1
2
nginx  //启动服务器 
nginx -s stop

配置文件default.conf

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
server {
listen 80;
server_name localhost;

#charset koi8-r;
#access_log /var/log/nginx/log/host.access.log main;

location / {
root /webcode;
index index.html index.htm index.php; # 增加index.php
}

#error_page 404 /404.html;

# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /webcode;
}

# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}

# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
location ~ \.php$ {
root /webcode; # 代码目录
fastcgi_pass phpfpm_db:9000; # 修改为phpfpm容器
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; # 修改为$document_root
include fastcgi_params;
}

# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}

到此,所有的配置成功。能够正常启动web服务了。

0x04 Docker-Composer管理复杂容器

Composer管理容器很好用,使用pip安装。请看这里:https://yeasy.gitbooks.io/docker_practice/content/compose/yaml_file.html
清晰明了,简单易懂。 下面直接看docker-compose.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
mysql_db:
image: mysql:5.5.48
environment:
- MYSQL_ROOT_PASSWORD=password
volumes:
- ./db/data:/var/lib/mysql
phpfpm_db:
image: phpfpm:with_mysql
links:
- mysql_db:mysql_db
volumes:
- ./web/webcode:/webcode
nginx_server:
image: nginx:1.8
links:
- phpfpm_db:phpfpm_db
volumes:
- ./server/conf/default_server.conf:/etc/nginx/conf.d/default.conf
volumes_from:
- phpfpm_db
ports:
- "80:80"

启动:

1
sudo docker-compose up -d

进入容器看看:

1
2
3
4
root@233c58909f66:/webcode# cat /etc/hosts
192.168.0.2 dockercomposenginxweb_mysql_db_1 c192080005f2
192.168.0.2 mysql_db c192080005f2 dockercomposenginxweb_mysql_db_1
192.168.0.2 mysql_db_1 c192080005f2 dockercomposenginxweb_mysql_db_1

看看线上的效果:

0x05 参考资源

Docker —— 从入门到实践
https://github.com/angelwhu/Docker/tree/master/docker-compose-nginx-web

文章作者: angelwhu
文章链接: https://www.angelwhu.com/paper/2016/04/08/docker-builds-nginx-php-mysql-environment/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 angelwhu_blog