准备
PowerShell
git
docker
- 使用
docker-machine
命令可以找到一台可用的Docker
主机
开包即用,不用看代码!
初始化
进入一个文件夹。
下载已经写好的开源项目
git clone https://github.com/huzhenghui/Docker-run-nginx-PHP-fpm-web-server-router-from-Windows-share-folder
进入开源项目文件夹
cd Docker-run-nginx-PHP-fpm-web-server-router-from-Windows-share-folder
更新子模块代码
git submodule update --init
使用管理员权限的PowerShell
运行共享文件夹到Docker
的脚本。
.\share-windows-folder-to-docker\share-windows-folder-to-docker.ps1 -workingDir . -volumeName nginx-PHP-fpm-web-server-router
查看文件夹是否共享成功
docker run --rm -v nginx-PHP-fpm-web-server-router:/share alpine ls /share
如果成功将看到开源项目的如下文件列表
LICENSE
docker-compose.yml
nginx
php
share-windows-folder-to-docker
使用PHP
内建的Web Server
的路由方式
启动PHP
内建web server
docker run -it --rm -v nginx-PHP-fpm-web-server-router:/nginx-PHP-fpm-web-server-router -p 80:80 php -S 0.0.0.0:80 -t /nginx-PHP-fpm-web-server-router/php/public index.php
正确启动将看到如下信息
PHP 7.2.1 Development Server started at Sun Feb 4 12:34:23 2018
Listening on http://0.0.0.0:80
Document root is /nginx-PHP-fpm-web-server-router/php/public
Press Ctrl-C to quit.
打开新的PowerShell
。
访问首页,此处使用环境变量获取Docker
主机的IP
地址,也可以自行输入。
Start-Process -FilePath ($env:DOCKER_HOST -replace '^tc(p://[.\d]+):.*', 'htt$1/')
index.php
中的内容为phpinfo
,从phpinfo
中可以看到这是PHP
内建的web server
。
查看一个不存在的页面,此处使用环境变量获取Docker
主机的IP
地址,也可以自行输入。
Start-Process -FilePath ($env:DOCKER_HOST -replace '^tc(p://[.\d]+):.*', 'htt$1/404')
可以看到仍旧是phpinfo
,区别在于其中的路径不同了,说明请求都被路由到index.php
文件了。
使用nginx
和PHP-fpm
的路由方式
使用docker-compose
启动
docker-compose up
正确启动将看到如下信息
Starting dockerrunnginxphpfpmwebserverrouterfromwindowssharefolder_php_1 ... done
Starting dockerrunnginxphpfpmwebserverrouterfromwindowssharefolder_web_1 ... done
Attaching to dockerrunnginxphpfpmwebserverrouterfromwindowssharefolder_php_1, dockerrunnginxphpfpmwebserverrouterfromwindowssharefolder_web_1
php_1 | [04-Feb-2018 12:38:42] NOTICE: fpm is running, pid 1
打开新的PowerShell
。
访问首页,此处使用环境变量获取Docker
主机的IP
地址,也可以自行输入。
Start-Process -FilePath ($env:DOCKER_HOST -replace '^tc(p://[.\d]+):.*', 'htt$1/')
index.php
中的内容为phpinfo
,从phpinfo
中可以看到这是nginx
连接PHP-fpm
。
查看一个不存在的页面,此处使用环境变量获取Docker
主机的IP
地址,也可以自行输入。
Start-Process -FilePath ($env:DOCKER_HOST -replace '^tc(p://[.\d]+):.*', 'htt$1/404')
可以看到仍旧是phpinfo
,区别在于其中的路径不同了,说明请求都被路由到index.php
文件了。
如果想看再看代码
项目文件结构如下
docker-compose.yml
nginx\
conf.d\
default.conf
php\
public\
index.php
share-windows-folder-to-docker\
share-windows-folder-to-docker.ps1
share-windows-folder-to-docker.ps1
是一个把Windows
中的文件夹共享到Docker
的脚本,具体工作原理见注释
index.php
中包含phpinfo
函数
docker-compose.yml
是容器编排文件
web:
image: nginx
ports:
- "80:80"
volumes:
- nginx-PHP-fpm-web-server-router:/nginx-PHP-fpm-web-server-router
command: /bin/bash -c "cp /nginx-PHP-fpm-web-server-router/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'"
links:
- php
php:
image: php:fpm
volumes:
- nginx-PHP-fpm-web-server-router:/nginx-PHP-fpm-web-server-router
其中包含两个服务web
和php
。
web
服务使用nginx
镜像,端口从80映射到80,把前面使用脚本共享的nginx-PHP-fpm-web-server-router
卷加载到/nginx-PHP-fpm-web-server-router
路径,关联到php
服务。
web
服务没有使用默认的启动命令,而是包含两部分,首先复制nginx
配置文件,配置文件的详细分析见下文。
cp /nginx-PHP-fpm-web-server-router/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf
然后启动nginx
。
nginx -g 'daemon off;'
php
服务使用php:fpm
镜像,把前面使用脚本共享的nginx-PHP-fpm-web-server-router
卷加载到/nginx-PHP-fpm-web-server-router
路径,此处注意,Docker
中容器之间是隔离的,web
服务和php
服务都需要访问的卷需要在每个服务中都加载一遍,而且加载的路径应当相同,使得程序按照路径访问的是相同的文件。
default.conf
是nginx
配置文件
server {
listen 80;
server_name localhost;
root /nginx-PHP-fpm-web-server-router/php/public;
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
fastcgi_pass php:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
设置监听80端口
listen 80;
设置服务器名
server_name localhost;
设置路由
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
把.php
后缀的文件传输到php
服务。
location ~ \.php$ {
fastcgi_pass php:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}