所谓LNMP,就是linux+nginx+mysql+php的组合,现在通过docker的各种方法进行配置。在 docker入门教程六:容器编排compose 有一个实例,就是使用lnmp来构建wordpress,但是只需要了2个镜像,一是Mysql数据库,二是wordpress,这个镜像集成了ningx+php的环境,所以部署起来会比较简单,以下是手工部署的方案。
手工版
先下载所需要的镜像:
1 | docker pull nginx |
这是我刚开始学习docker时,使用了mysql8.0的版本,折腾了很久,建议还是使用5.7版本就可以了
mysql
先复制配置文件,然后再运行。1
2
3
4
5
6
7
8
9
10
11mkdir -p /home/docker_lnmp/mysql/{data,conf.d}
docker run --name mysql -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql
docker cp mysql:/etc/mysql/conf.d /home/docker_lnmp/mysql/
docker rm -f mysql
docker run --name mysql \
-v /home/docker_lnmp/mysql/data/:/var/lib/mysql \
-v /home/docker_lnmp/mysql/conf.d/:/etc/mysql/conf.d \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
-d mysql
php
先将/usr/local/etc/php-fpm.d下面的配置文件复制出来。
1 | mkdir -p /home/docker_lnmp/php/{conf.d,php-fpm.d,logs} |
由于官方的PHP里面没有GD库、MYSQL扩展,所以必须要安装相应的扩展,先准备Dockerfile文件,再构建1
2
3
4
5
6
7
8
9
10
11
12[root@host php7.1]# cat Dockerfile
FROM php:7.1-fpm
RUN apt-get update && apt-get install -y \
libfreetype6-dev \
libjpeg62-turbo-dev \
libmcrypt-dev \
libpng-dev \
&& docker-php-ext-install -j$(nproc) iconv mcrypt 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
[root@host php7.1]# docker build -t php-fpm-mysql:v7.1 .
然后再运行,注意,这边使用了link方式进行了网络的互连,1
2
3
4
5
6
7
8docker run --name php7.1 \
-p 9000:9000 \
-v /home/docker_lnmp/php/php-fpm.d/:/usr/local/etc/php-fpm.d \
-v /home/docker_lnmp/php/conf.d/:/usr/local/etc/conf.d \
-v /home/docker_lnmp/nginx/www:/var/www/html \
-e TIMEZONE=Asia/Shanghai \
--link mysql:mysql \
-d php-fpm-mysql:v7.1
另外这个php是没有php.ini文件,默认是加载这/usr/local/etc/php以及/usr/local/etc/php/conf.d/里面的内容。
1 | root@dda208774103:/var/www/html# ls -l /usr/local/etc/php |
nginx
先复制出相关的配置文件,再运行1
2
3
4
5
6
7
8
9
10
11
12
13mkdir -p /home/docker_lnmp/nginx/{www,logs,conf.d}
docker run --name nginx -p 80:80 -d nginx
docker cp nginx:/etc/nginx/conf.d /home/docker_lnmp/nginx/
docker rm -f nginx
docker run --name nginx \
-p 80:80 \
--link php7.1:php7.1 \
--link mysql:mysql \
-v /home/docker_lnmp/nginx/conf.d/:/etc/nginx/conf.d \
-v /home/docker_lnmp/nginx/www/:/usr/share/nginx/html \
-v /home/docker_lnmp/nginx/logs/:/var/log/nginx \
-d nginx
然后再修改配置文件如下:
fastcgi_pass原行的配置是127.0.0.1:9000,需要修改为link名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
30server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.php index.html index.htm;
}
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
location ~ \.php$ {
- fastcgi_pass 127.0.0.1:9000;
+ fastcgi_pass php7.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.ht {
deny all;
}
}
由于配置文件有修改过了,需要重新一下容器:docker restart nginx
也可以使用docker pull richarvey/nginx-php-fpm && docker run -itd --name lnmp_web -p 80:80 --mount type=bind,src=/app/wwwroot,dst=/var/www/html richarvey/nginx-php-fpm来处理。即nginx跟php合并在一个容器中。
测试运行PHP
如果你的php有编译了mysqli.so模块的话,运行下面就不会报错了。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 建立连接
try{
//这里的mysql:host=mysql,后面这个mysql就是我们的mysql容器
//用户名 root 是默认的
//密码 123456 就是我们在mysql容器设置的环境变量
$dbh = new PDO("mysql:host=mysql;dbname=mysql", "root", 123456);
$dbh->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
$dbh->exec("SET CHARACTER SET utf8");
$dbh=null; //断开连接
}catch(PDOException $e){
print"Error!:".$e->getMessage()."<br/>";
die();
}
// 错误检查S
// 输出成功连接
echo "<h1>成功通过 PDO 连接 MySQL 服务器</h1>" . PHP_EOL;
phpinfo();
部署phpmyadmin
wget https://files.phpmyadmin.net/phpMyAdmin/4.8.5/phpMyAdmin-4.8.5-all-languages.zip下载到/home/docker_lnmp/nginx/www下,解压之后,修改下面2个文件,如果不修改的话,则是报mysqli_real_connect(): (HY000/2002): No such file or directory这个错误。1
2
3
4
5[root@host phpmyadmin]# grep mysql config.sample.inc.php
$cfg['Servers'][$i]['host'] = 'mysql';
[root@host phpmyadmin]# grep mysql libraries/config.default.php
$cfg['Servers'][$i]['host'] = 'mysql';
这时登陆还会报错,Error!:SQLSTATE[HY000] [2054] The server requested authentication method unknown to the client,这是由于出现上面的报错是由于mysql8使用了caching_sha2_password插件来验证密码,而PHP7.1不支持,修改使用mysql_native_password就可以。
1 | ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '123456'; |
部署wordpress
下载wget https://cn.wordpress.org/latest-zh_CN.zip到/home/docker_lnmp/nginx/www下,解压之后,由于nginx以及php是以www-data这个用户来运行的,所以要修改相应的权限,不然创建临时文件时就会提示权限不足。1
2
3
4
5
6
7
8
9
10
11
12
13[root@host www]# docker exec -it nginx chown www-data:www-data /usr/share/nginx/html/wordpress -R
[root@host www]#
[root@host www]# docker exec -it nginx chmod 755 /usr/share/nginx/html/wordpress -R
[root@host www]#
[root@host www]# docker exec -it nginx ls -l /usr/share/nginx/html/
total 22284
-rw-r--r-- 1 root root 20 Mar 18 01:26 index.html
-rw-r--r-- 1 root root 17 Mar 23 06:30 info.php
-rw-r--r-- 1 root root 11998579 Jan 11 10:02 latest-zh_CN.zip
-rw-r--r-- 1 root root 612 Mar 23 06:26 p.php
-rw-r--r-- 1 root root 10794370 Jan 26 03:37 phpMyAdmin-4.8.5-all-languages.zip
drwxr-xr-x 13 root root 4096 Mar 23 10:26 phpmyadmin
drwxr-xr-x 5 www-data www-data 4096 Mar 23 11:25 wordpress
在宿主机上面查看权限,则user id是33
1 | [root@host www]# ll |
Dockerfile简单版
目录如下:
1 | [root@host lnmp-fdm]# tree |
php/Dockerfile 如下:1
2
3
4
5
6
7
8
9
10FROM php:7.1-fpm
RUN apt-get update && apt-get install -y \
libfreetype6-dev \
libjpeg62-turbo-dev \
libmcrypt-dev \
libpng-dev \
&& docker-php-ext-install -j$(nproc) iconv mcrypt 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
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
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37version: '3'
services:
### PHP-FPM Container #######################################
php-fpm:
build:
context: ./php
volumes:
- /home/docker_lnmp/nginx/www:/var/www/html
ports:
- "9000:9000"
depends_on:
- mysql
### Nginx Server Container ##################################
nginx:
image: nginx
volumes:
- /home/docker_lnmp/nginx/www:/var/www/html
- /home/docker_lnmp/nginx/logs:/var/log/nginx
- /home/docker_lnmp/nginx/conf.d/:/etc/nginx/conf.d:ro
ports:
- "80:80"
- "443:443"
depends_on:
- php-fpm
- mysql
### MySQL Container #########################################
mysql:
image: mysql:5.7
volumes:
- /home/docker_lnmp/mysql/:/var/lib/mysql
ports:
- "3306:3306"
environment:
- MYSQL_ROOT_PASSWORD=123456
文件目录如下:
1 | [root@host lnmp-fdm]# tree -L 3 /home/docker_lnmp/ |
检查yaml文件的配置是否正常:1
2
3
4[root@host lnmp-fdm]# docker-compose config
ERROR: yaml.scanner.ScannerError: while scanning for the next token
found character '\t' that cannot start any token
in "./docker-compose.yml", line 17, column 1
调整完了之后,运行docker-compose up,由于这是第二次运行,php就没有bulid了,就直接创建容器了。1
2
3
4
5
6
7[root@host lnmp-fdm]# docker-compose up
Creating lnmp-fdm_mysql_1 ... done
Creating lnmp-fdm_php-fpm_1 ... done
Creating lnmp-fdm_nginx_1 ... done
Attaching to lnmp-fdm_mysql_1, lnmp-fdm_php-fpm_1, lnmp-fdm_nginx_1
mysql_1 | Initializing database
mysql_1 | 2019-03-24T05:25:59.710656Z 0
可以看到,三个容器已经同时运行了。1
2
3
4
5[root@host ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
75503df18155 nginx "nginx -g 'daemon of…" About a minute ago Up About a minute 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp lnmp-fdm_nginx_1
0826d1bba4b0 lnmp-fdm_php-fpm "docker-php-entrypoi…" About a minute ago Up About a minute 0.0.0.0:9000->9000/tcp lnmp-fdm_php-fpm_1
31c434bbb068 mysql:5.7 "docker-entrypoint.s…" About a minute ago Up About a minute 0.0.0.0:3306->3306/tcp, 33060/tcp lnmp-fdm_mysql_1
参考资料
https://www.awaimai.com/2120.html
docker-lnmp 多容器部署 Laravel 方案分享
Docker 中的 PHP 如何安装扩展:https://my.oschina.net/antsky/blog/1591418
PHP错误:SQLSTATE[HY000] [2054] The server requested authentication method unknown to the client
phpMyAdmin 登录报错:mysqli_real_connect(): (HY000/2002): No such file or directory