我试图在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;
}
}
但是,我想在example.com/status
服务,而不是在status.example.com
服务。
我期待这将工作,但从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
)也可能是一个no-op,因为如果$uri
没有在.php
中结束,我们怎么应该在'.php$
location
中结束呢?(同样,您也可以自由地尝试删除第一条重写规则,并将SCRIPT_FILENAME
中的$uri
替换为$fastcgi_script_name
,看看事情是否仍然有效,但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工作良好。问题是源代码中的所有路径都是绝对的,所以它们不会指向我们的文件所在的子目录。解决方案是做一些我从一开始就不愿意做的事情:将它托管在子域中。