Nginx的主机应用程序在不同的位置

我试图在nginx + php-fpm中的特定位置提供CachetHQ 。 这个文档给出了在status.example.com (其工作原理)中的例子:

 server { listen 80; server_name status.example.com; root /var/www/Cachet/public; index index.php; location / { try_files $uri /index.php$is_args$args; } location ~ \.php$ { include fastcgi_params; fastcgi_pass 127.0.0.1:9000; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_index index.php; fastcgi_keep_conn on; } } 

不过,我不想在status.example.com中投放,我想在example.com/status投放。

我期待这会工作,但从error.log我看到它正在尝试/etc/nginx/htmlindex.php ,但它应该是/mnt/data/site/www-cachet/public/index.php

 location /status/ { index index.php; root /mnt/data/site/www-cachet/public; try_files $uri index.php$is_args$args; location ~ ^/status/.+\.php$ { root /mnt/data/site/www-cachet/public; include fastcgi_params; fastcgi_pass unix:/tmp/php-fpm.sock; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_index index.php; fastcgi_keep_conn on; } } 

让我从你声称的原始配置开始,并尝试根据你的要求修改它,结果如下:

 location ^~ /status { alias /var/www/Cachet/public; index index.php; location = /status { return 302 /status/; } location / { try_files $uri /status/index.php$is_args$args; } location ~ \.php$ { include fastcgi_params; fastcgi_pass 127.0.0.1:9000; rewrite ^/status/(.*) /$1; rewrite ^(.*)/ $1/index.php; # who knows what fastcgi_index is for? fastcgi_param SCRIPT_FILENAME $document_root$uri; fastcgi_keep_conn on; } } 

基本上,你想在这里使用alias而不是root ,也可能在最后的try_files也有一个绝对路径。 我不认为需要在嵌套的位置中添加额外的前缀,但是您可能要确保根位置是与^~修饰符的最终匹配。

我猜,主要的技巧是,即使使用alias指令,事情也不像使用正确的root那样花哨,所以,您必须确保SCRIPT_FILENAME设置正确。 这部分似乎没有被记录得非常清楚,我也懒得去测试$fastcgi_script_name ngx变量和fastcgi_index指令是否和alias很好地匹配 – 而不是试图确定这些工作(或不是)如何工作根据情况做一些rewrite规则,然后根据重写规则的结果构建SCRIPT_FILENAME 。 🙂

然而,这样说,我认为第二个重写规则(以及它所取代的fastcgi_index )也可能是没有操作的,因为如果$uri是我们应该如何结束在\.php$ location已经没有以.php ? (同样,你也可以自由地尝试删除第一个重写规则,并用$fastcgi_script_name替换SCRIPT_FILENAME $uri ,看看事情是否仍然有效,但是2009年的互联网可能表明它们没有。

你的try_files不正确。
你可以这样做:

 index index.php; root /mnt/data/site/www-cachet/public; location / { if (!-e $request_filename) { rewrite ^(.*)$ /index.php?$1 last; break; } } location ~ ^/status/.+\.php$ { root /mnt/data/site/www-cachet/public; include fastcgi_params; fastcgi_pass unix:/tmp/php-fpm.sock; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_index index.php; fastcgi_keep_conn on; } 

经过这么多个小时的尝试,很多组合,我得到它的工作方式是:

 location ^~ /status { alias /mnt/data/site/www-cachet/public; try_files $uri $uri/ @status; location = /status/ { rewrite /status/$ /status/index.php; } location ~ ^/status/(.+\.php)$ { fastcgi_pass unix:/tmp/php-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /mnt/data/site/www-cachet/public/$1; include fastcgi_params; } } location @status { rewrite /status/(.*)$ /status/index.php?/$1 last; } 

最重要的是fastcgi_param ,我必须将其设置为绝对路径而不是$document_root$fastcgi_script_name或类似的东西。 我不确定这是否是一个好的实践,但添加alias到块不起作用,nginx或FastCGI都不显示他们正在尝试读取文件的路径。

不过,我无法让CachetHQ运作良好。 问题是源代码中的所有路径都是绝对的,所以它们不会指向托管我们文件的子目录。 解决办法是做一些我从一开始就不情愿:托管在一个子域。