一, 环境准备
每个容器的 IP 地址:
- * Nginx: 172.16.10.10
- * MySQL: 172.16.10.20
- * PHP: 172.16.10.30
搭建 LNMP 注意事项:
* 各个容器的数据实现持久化;
* 为容器分配固定的 IP 地址, 防止容器重建后, IP 地址发生变化, 徒增不必要的麻烦;
* 由于客户端只需要访问 Nginx 的 80 端口, 然后通过 Nginx 去调用 PHP 连接数据库,
所以只需要将 Nginx 的 80 端口使用 "-p" 选项映射到宿主机即可, 其他容器, 不必映射, 相比较而言, 也安全了些.
二, 案例实施
(1), 创建一个自定义网络
- [root@docker ~]# docker network create -d bridge --subnet 172.16.10.0/24 --gateway 172.16.10.1 lnmp
- // 创建自定义网络, 并指定网段, 网关, 只有定义了网段, 才可以使用此网络为容器分配固定 IP
(2), 运行 nginx 容器
- [root@docker ~]# docker run -itd --name test nginx
- // 随便运行一个容器, 以便生成 nginx 中所需的配置文件
- [root@docker ~]# mkdir /wwwroot // 用于网站的访问主目录
- [root@docker ~]# mkdir /docker // 用于 Nginx 的配置文件
- // 创建目录用于挂载 nginx 容器的相关目录
- [root@docker ~]# docker cp test:/etc/nginx /docker/
- // 将 nginx 容器中的 nginx 主目录复制到本地创建的目录
- [root@docker ~]# ls /docker/
- nginx
- [root@docker ~]# docker cp test:/usr/share/nginx/html /wwwroot/
- // 将 nginx 容器中的网页根目录复制到本地创建的目录
- [root@docker ~]# ls /wwwroot/
- HTML
- [root@docker ~]# docker run -itd --name nginx -v /docker/nginx:/etc/nginx -v /wwwroot/HTML:/usr/share/nginx/HTML -p 80:80 --network lnmp --ip 172.16.10.10 nginx
- // 基于刚刚创建的 nginx 网络运行 Nginx 容器, 并指定其 IP 地址;
- // 使用 "-v" 选项分别将目录挂载到 nginx 的配置文件及网页根目录, 以便实现数据持久化;
- // 在实现数据的持久化过程中, 也解决了 nginx 容器内无法使用一些基本命令的问题,
- // 若需要更改 nginx 配置文件或网络根目录, 直接在本地的 / data 目录下进行相应的操作即可.
- // 运行 Nginx 容器并测试
- [root@docker ~]# echo "hello world"> /wwwroot/HTML/index.HTML
- [root@docker ~]# curl 127.0.0.1
- hello world
(3), 运行 MySQL 容器
- [root@docker ~]# docker run --name MySQL -e MYSQL_ROOT_PASSWORD=123.com -d -p 3306:3306 --network lnmp --ip 172.16.10.20 MySQL:5.7
- // 基于 lnmp 网络运行 MySQL 镜像, 并指定其 IP 地址;
- //MYSQL_ROOT_PASSWORD=123.com" 是为指定 MySQL 数据库的 root 密码
- // 若需要使用第三方图形化工具连接数据库, 只需要加 "-p" 选项将容器的 3306 端口映射到宿主机即可.
(4), 运行 PHP 容器
- [root@docker ~]# docker run -itd --name phpfpm -p 9000:9000 -v /wwwroot/HTML:/usr/share/nginx/HTML --network lnmp --ip 172.16.10.30 PHP:7.2-fpm
- // 运行一个名为 phpfpm 的容器, 并映射端口, 挂载相应的目录, 指定 IP 地址
- // 看挂载的目录跟 nginx 主目录一样, 是因为需要修改 nginx 容器的配置文件
- [root@docker ~]# cd /wwwroot/HTML/
- [root@docker HTML]# VIM test.PHP
- <?PHP
- phpinfo();
- ?>
(5), 修改 nginx 配置文件, 使 nginx 和 PHP 连接
- [root@docker ~]# VIM /docker/nginx/conf.d/default.conf
- location / {
- root /usr/share/nginx/HTML;
- index index.HTML index.htm index.PHP ; // 此段添加: index.PHP
- }
- location ~ \.PHP$ {
- root /usr/share/nginx/HTML; // 修改其网页根目录位置
- fastcgi_pass 172.16.10.30:9000; // 更改为 PHP 容器的 IP 地址
- fastcgi_index index.PHP;
- fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; // 添加 $document_root 变量
- include fastcgi_params;
- }
- [root@docker ~]# docker restart nginx // 重启 nginx 服务
- nginx
到此, 去浏览器验证, nginx 服务和 PHP 服务的界面...
(6), 测试 PHP 容器和 MySQL 的协调工作
说明 nginx 和 PHP 的连接, 没有问题, 接下来是 PHP 和 MySQL 的连接.
在这里我们使用一个 phpMyAdmin 的数据库管理工具.
- [root@docker ~]# wget https://files.phpmyadmin.net/phpMyAdmin/4.9.1/phpMyAdmin-4.9.1-all-languages.zip
- // 下载 phpmyadmin 源码包
- [root@docker ~]# unzip phpMyAdmin-4.9.1-all-languages.zip // 解压源码包
- [root@docker ~]# mv phpMyAdmin-4.9.1-all-languages /wwwroot/HTML/phpmyadmin // 更改解压后的目录名称
- [root@docker ~]# VIM /docker/nginx/conf.d/default.conf // 编辑 Nginx 主配置文件
- location /phpmyadmin {
- root /usr/share/nginx/HTML;
- index index.HTML index.htm index.PHP ;
- }
- location ~ /phpmyadmin/(?<after_ali>(.*)\.(PHP|php5)?$) {
- root /usr/share/nginx/HTML;
- fastcgi_pass 172.16.10.30:9000;
- fastcgi_index index.PHP;
- fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
- include fastcgi_params;
- }
- [root@docker ~]# docker restart nginx // 重新启动 nginx 容器
- [root@docker ~]# docker ps | grep nginx 确保 nginx 容器正常运行
- f8442dc794b9 nginx "/docker-entrypoint...." About an hour ago Up 24 seconds 0.0.0.0:80->80/tcp nginx
访问浏览器测试:
OK, 看到报错, 就说明至此, 做的没有问题, 正常来说, 就是会提示此错误, 因为在正常编译安装 PHP 时, 都需要增加 "--with-mysql..." 等一些相关选项, 看到这个页面, 很显然, 我们运行的这个 PHP 容器并没有增加关于数据库的选项, 接下来, 就解决这些问题.
(7), 解决 PHP 容器不支持关联 MySQL 数据库
登录 docker 官网, 搜索 "PHP" 并点击进入, 如下:
已经在 Docker 官网上看到了答案, 接下里基于原本的 PHP 镜像编写 Dockerfile, 生成新的镜像使其支持这个功能!
- [root@docker HTML]# VIM Dockerfile #编写 Dockerfile 文件, 文件开头是复制的官网提供的代码
- FROM PHP:7.2-fpm
- RUN apt-get update && apt-get install -y \
- libfreetype6-dev \
- libjpeg62-turbo-dev \
- libpng-dev \
- && docker-PHP-ext-install -j$(nproc) iconv \
- && docker-PHP-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
- && docker-PHP-ext-install -j$(nproc) gd \ // 增加斜杠
- && docker-PHP-ext-install mysqli pdo pdo_mysql // 增加该行, 使其能支持连接 MySQL 功能
- // 编写完成后, 保存退出即可
- [root@docker HTML]# docker build -t phpmyadmin . // 生成新的镜像, 不要落下命令末尾的 ".".
- [root@docker HTML]# docker rm -f phpfpm // 原来的 PHP 容器可以删除了
- [root@docker HTML]# docker run -itd --name phpfpm -p 9000:9000 -v /wwwroot/HTML:/usr/share/nginx/HTML --network lnmp --ip 172.16.10.30 phpmysql
- // 基于新创建的 PHP 镜像运行新的 PHP 容器
- [root@docker ~]# cd /wwwroot/HTML/phpmyadmin/
- [root@docker phpmyadmin]# mv config.sample.inc.PHP config.inc.PHP
- [root@docker phpmyadmin]# VIM config.inc.PHP // 编写 PHP 的配置文件
$cfg['Servers'][$i]['host'] = '172.16.10.20'; 更改其为 MySQL 容器的 IP 地址
- [root@docker phpmyadmin]# docker restart phpfpm // 重启 PHP
- phpfpm
- [root@docker phpmyadmin]# docker ps | grep phpfpm // 确保 PHP 容器运行正常
- c9feb2df0603 phpmysql "docker-php-entrypoi..." 11 minutes ago Up About a minute 0.0.0.0:9000->9000/tcp phpfpm
来源: http://blog.51cto.com/14306186/2517130