我目前正在尝试将 3 个应用程序从一个存储库拆分为 3 个,但保留 url 结构,因此同一域下的不同位置基本上必须由不同的应用程序交付。
我正在努力解决的是其中一个应用程序需要成为不存在网址的后备,因此如果第一个不匹配,第二个不匹配,那么第三个应该处理请求
我得到的结构是:
/etc/nginx/sites-enabled/main_site,在这里,除了 server_name 和日志include /etc/nginx/subsites-enabled/*
,我有 3 个配置文件,每个应用程序一个。
3 个配置文件中的每一个都包含一个位置块。
我已经在正则表达式中尝试了负前瞻(基本上是尝试对其他应用程序处理的 url 进行硬编码)但失败了。
所以,总结一下:
/ 和 /community 应该由 /etc/nginx/subsites-enabled/example.org/home 提供(一些 perl 脚本)
/news 应该由 /etc/nginx/subsites-enabled/example.org/news (wordpress) 提供
其他一切都应该由 /etc/nginx/subsites-enabled/example.org/app (cake app) 提供
perl 位工作正常。我遇到的问题是该应用程序正在接管新闻(可能是因为它匹配 .*),我尝试了各种选项(我已经在这呆了 2 天),但没有一个解决了所有问题(有时静态资产不起作用等)。
我的配置是:
/etc/nginx/sites-enabled/example.org:
server {
listen 80;
server_name example.org;
error_log /var/log/nginx/example.org.log;
include /etc/nginx/subsites-enabled/example.org/*;
}
Run Code Online (Sandbox Code Playgroud)
/etc/nginx/subsites-enabled/example.org/home:
location = / {
rewrite ^.*$ /index.pl last;
}
location ~* /community(.*) {
rewrite ^.*$ /index.pl last;
}
location ~ \.pl {
root /var/www/vhosts/home;
access_log /var/log/nginx/home/access.log;
error_log /var/log/nginx/home/error.log;
include /etc/nginx/fastcgi_params;
fastcgi_index index.pl;
fastcgi_param SCRIPT_FILENAME /var/www/vhosts/home$fastcgi_script_name;
fastcgi_pass unix:/var/run/fcgiwrap.socket;
}
Run Code Online (Sandbox Code Playgroud)
/etc/ngins/subsites-enabled/news
location /news {
access_log /var/log/nginx/news/access.log;
error_log /var/log/nginx/news/error.log debug;
error_page 404 = /news/index.php;
root /var/www/vhosts/news;
index index.php;
if (!-e $request_filename) {
rewrite ^.*$ /index.php last;
}
location ~ \.php {
include /etc/nginx/fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/vhosts/news$fastcgi_script_name;
}
}
Run Code Online (Sandbox Code Playgroud)
/etc/nginx/subsites-enabled/app:
location ~ .* {
access_log /var/log/nginx/app/access.log;
error_log /var/log/nginx/app/error.log;
rewrite_log on;
index index.php;
root /var/www/vhosts/app/app/webroot;
if (-f $request_filename) {
expires 30d;
break;
}
if (!-e $request_filename) {
rewrite ^.*$ /index.php last;
}
location ~ \.php {
include /etc/nginx/fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/vhosts/app/app/webroot$fastcgi_script_name;
}
}
Run Code Online (Sandbox Code Playgroud)
cyb*_*x86 52
您的配置有一些问题,两个相关的问题是:
例如,使用 URL example.org/news/test.htm
location /news
块将匹配它/news/test.htm
- 这不会改变,只是因为它在位置块中/var/www/vhosts/news/news/test.htm
if (!-e $request_filename)
语句应该捕获这个不存在的文件/index.php
last
流程重新开始(打破位置块)/index.php
现在被location /app block
.当您转到应用程序位置块时,上面提到的带有 root 指令的问题会变得更加复杂。与“新闻”块不同,您可以想象从路径中删除“新闻”(因为它将被重新添加),您不能对以“webroot”结尾的应用程序路径执行此操作。
解决方案在于alias
指令。这不会更改 document_root,但会更改用于为请求提供服务的文件路径。遗憾的是,rewrite
并try_files
往往意外行为有点用alias
。
让我们从一个简单的例子开始——没有 PHP——只有 HTML 和你的 Perl 块——但是有一个匹配你的文件夹结构(在 Nginx 1.0.12、CentOS 6 上测试):
server {
server_name example.org;
error_log /var/log/nginx/example.org.error.log notice;
access_log /var/log/nginx/example.org.access.log;
rewrite_log on;
location = / {
rewrite ^ /index.pl last;
}
location ^~ /community {
rewrite ^ /index.pl last;
}
location ~ \.pl {
root /var/www/vhosts/home;
[fastcgi_stuff...]
}
location ^~ /news {
alias /var/www/vhosts/news;
index index.htm;
try_files $uri $uri/ /news/index.htm;
}
location ^~ /app {
alias /var/www/vhosts/app/app/webroot;
index index.htm;
try_files $uri $uri/ /app/index.htm;
}
location / {
rewrite ^/(.*) /app/$1 last;
}
}
Run Code Online (Sandbox Code Playgroud)
location = /
- 只会匹配根路径location ^~ /community
- 将匹配所有以 /community 开头的路径location ~ \.pl
- 将匹配所有包含 .pl 的文件location ^~ /news
- 将匹配所有以 /news 开头的路径location ^~ /app
- 将匹配所有以 /app 开头的路径location /
- 将匹配上面不匹配的所有路径您应该能够删除^~
- 但它可能会提供轻微的性能改进,因为一旦找到匹配项,它就会停止搜索。
虽然重新添加 PHP 块应该是一件简单的事情,但不幸的是,有一个小困难 - try_files
(和您的重写)最终不会将所需的路径传递给嵌套的位置块 - 并且alias
在只有扩展名时使用在位置块中指定的不起作用。
一种解决方案是使用单独的位置块与 alias 指令一起执行捕获 - 它不是很优雅,但据我所知,它确实有效(再次在 Nginx 1.0.12、CentOS 6 上测试)当然,我没有设置 CakePHP、Wordpress 和 Perl——我只是在每个文件夹中使用了几个 PHP 和 HTML 文件)
server {
server_name example.org;
error_log /var/log/nginx/example.org.error.log notice;
access_log /var/log/nginx/example.org.access.log;
rewrite_log on;
location = / {
rewrite ^ /index.pl last;
}
location ^~ /community {
rewrite ^ /index.pl last;
}
location ~ \.pl {
root /var/www/vhosts/home;
access_log /var/log/nginx/home.access.log;
error_log /var/log/nginx/home.error.log;
include /etc/nginx/fastcgi_params;
fastcgi_index index.pl;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/var/run/fcgiwrap.socket;
}
location /news {
access_log /var/log/nginx/news.access.log;
error_log /var/log/nginx/news.error.log notice;
alias /var/www/vhosts/news;
index index.php;
try_files $uri $uri/ /news/index.php;
}
location ~* ^/news/(.*\.php)$ {
access_log /var/log/nginx/news.php.access.log;
error_log /var/log/nginx/news.php.error.log notice;
alias /var/www/vhosts/news/$1;
try_files "" /news/index.php;
include /etc/nginx/fastcgi_params;
fastcgi_index index.php;
fastcgi_param SCRIPT_NAME $1;
fastcgi_param SCRIPT_FILENAME /var/www/vhosts/news/$1;
fastcgi_pass 127.0.0.1:9000;
}
location /app {
alias /var/www/vhosts/app/app/webroot;
access_log /var/log/nginx/app.access.log;
error_log /var/log/nginx/app.error.log notice;
index index.php;
try_files $uri $uri/ /app/index.php;
}
location ~* ^/app/(.*\.php)$ {
access_log /var/log/nginx/news.access.log;
error_log /var/log/nginx/news.error.log notice;
alias /var/www/vhosts/app/app/webroot/$1;
try_files "" /app/index.php;
include /etc/nginx/fastcgi_params;
fastcgi_index index.php;
fastcgi_param SCRIPT_NAME $1;
fastcgi_param SCRIPT_FILENAME /var/www/vhosts/app/app/webroot/$1;
fastcgi_pass 127.0.0.1:9000;
}
location / {
rewrite ^/(.*) /app/$1 last;
}
}
Run Code Online (Sandbox Code Playgroud)
上面的配置,采用了上面的简单配置,做了两处改动:
location ~* ^/news/(.*\.php)$
- 将匹配所有以 .php 结尾的文件,路径以 /news/ 开头location ~* ^/app/(.*\.php)$
- 将匹配所有以 .php 结尾的文件,路径以 /app/ 开头^~
匹配 - 这是必需的,以便添加的两个位置块可以与路径匹配(否则匹配将在 /news 或 /app 块上停止)。需要注意的是,位置匹配的顺序在这里很重要:
=
)^~
第二个匹配匹配的正则表达式将取代直字符串!
重要的一点是,当捕获与别名一起使用时,整个 URL 将被替换 - 而不仅仅是前导文件夹。不幸的是,这意味着它$fastcgi_script_name
是空的 - 所以,我用$1
上面代替。
我相信您需要进行一些更改,但基本前提应该是功能性的。您应该能够根据需要将块分成多个文件 - 排序不应影响配置。