我们可能会遇到需要在一个域名下用几套程序来构建一个网站,这时候可能需要在在不同的目录下绑定不同的网站。
比如 根目录 /
是用 Laravel 构建的cms程序,/blog
下绑定的是一个 wordpress 开源博客程序。
问题一:如何将不同程序的代码目录绑定到一个域名下的不同路径?
一般来说各个网站的程序代码在服务器上存放的位置是并列的。比如 /data/wwwroot/cms/
,/data/wwwroot/blog
我们要做的是将各个代码目录绑定在一个域名下的目录树上。
比如 http://demo.com/
指向访问cms程序
http:/demo.com/blog
访问博客程序,(有点像 Linux文件系统的挂载)
处理方法是在 server{}
中根据请求路径设置不同的 root
( 网站根目录)
情况一, server 块下只有一个域名,解决方法:
server {
server_name demo.com ;
index index.php index.html;
if ($host ~* ^demo\.com$) {
set $rootdir "/data/wwwroot/cms";
}
if ($request_uri ~* ^/blog/?.*) {
set $rootdir "/data/wwwroot/blog";
}
//如果有论坛程序,可以再绑定到 /bbs 目录
if ($request_uri ~* ^/bbs/?.*) {
set $rootdir "/data/wwwroot/bbs";
}
root $rootdir;
}
这种情况比较简单,根据请求路径设置不同的根目录路径就行了。
情况二 server 块下有多个域名
下面代码做参考
server {
server_name demo.com api.demo.com;
index index.php index.html;
set $flag 0;
if ($host ~* ^demo\.com$) {
set $flag "${flag}1";
}
if ($request_uri ~* ^/blog/?.*) {
set $flag "${flag}2";
}
if ($flag = "01") {
set $rootdir "/data/wwwroot/cms";
}
// 当请求域名为 demo.com, 并且 路径为 /blog 开头时,设置代码根目录
if ($flag = "012") {
set $rootdir "/data/wwwroot/blog";
}
root $rootdir;
}
因为 Nginx 不支持if的多条件 and 和 or, 这里用变通的方式,通过设置了一个 $flag
变量的值实现了 and,当 $flag
值为 012
时,表示 请求域名为 demo.com, 并且 路径为 /blog 开头,则设置代码根目录为blog的目录/data/wwwroot/blog
, 当 $flag
值为 01
表示,请求域名为 demo.com
, 路径不为 blog
,则设置代码根目录为 cms的目录 /data/wwwroot/cms
问题二 如何用不同的PHP 版本运行不同的网站?
假如 blog 程序比较老只能运行 PHP5 ,而cms 程序比较新, 只能运行 PHP7 , 这时候要解决在一个 server 块下 ,多个PHP 版本并行的问题。
我们一般一个 server 块下只有一个 PHP 处理块, 例如:
location /{
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.(php)?$ {
fastcgi_pass 127.0.0.1:9000;
if ($request_filename !~* \.php$) {
return 403;
}
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
首先要并行多个版本的PHP ,要满足两个条件:
- 需要将它们的启动在不同的服务器,或者同一服务器下的不同的端口上, 例如把 PHP7 启动在
9000
端口下, 把 PHP5 启动在9001
端口下。 - 为了能让请求进到不同的PHP 处理,两个处理块的判断规则必须不一样,不能都是
location ~ \.(php)?$
实现代码如下:
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location /blog {
try_files $uri $uri/ /blog_index.php?$query_string;
}
//运行PHP7
location ~ \.(php)?$ {
fastcgi_pass 127.0.0.1:9000;
if ($request_filename !~* \.php$) {
return 403;
}
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
//运行PHP5
location ^~ /blog_index.php {
fastcgi_pass 127.0.0.1:9001;
if ($request_filename !~* \.php$) {
return 403;
}
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
一般程序的入口文件名都是 index.php
, 在blog的程序根目录下可能没有 blog_index.php
这个文件, 但是为了区分两个 PHP 处理块的 location 判断规则, 我们需要把入口文件强行重名命。
另外 ^~
表示非正则匹配, 匹配到后不继续进行正则匹配, 所以不会再走到另一个PHP 处理块中。
总结
Nginx 中 if 、location 、rewrite、变量 很重要, 能够深刻理解 location 匹配、rewrite地址重写,并能灵活应用, 基本上绝大多数问题都能找到解决方法。
转载请注明:大后端 » Nginx 一个域名下部署多个网站运行多个PHP 版本