There are two hosts with a PHP-FPM pool each - one.com and two.com. I would like one.com/two to pass through and show two.com using two's pool, but I seem to be having difficulty.
Through alias
and try_files
, I've managed to get static assets from two.com's files served via. one.com/two/path/to/asset.ext, but PHP requests e.g. one.com/two/index.php
(and requests to files which don't exist in two's files) seem to be falling back to the last rule and showing one.com's application 404 page instead.
Here's the location configuration for one.com:
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~* ^/two$ {
return 301 /two/;
}
location /two/ {
alias /srv/two.com/public/;
try_files $uri $uri/ /two/index.php$is_args$args;
}
location ~* ^/two/(.+\.php)$ {
alias /srv/two.com/public/$1;
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/7.1-two.com.sock;
}
location ~* \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/7.1-one.com.sock;
}
snippets/fastcgi-php.conf
:
# regex to split $uri to $fastcgi_script_name and $fastcgi_path
fastcgi_split_path_info ^(.+\.php)(/.+)$;
# Check that the PHP script exists before passing it
try_files $fastcgi_script_name =404;
# Bypass the fact that try_files resets $fastcgi_path_info
# see: http://trac.nginx.org/nginx/ticket/321
set $path_info $fastcgi_path_info;
fastcgi_param PATH_INFO $path_info;
fastcgi_index index.php;
include snippets/fastcgi_params.conf;
$1
for the alias seems to be correct - I replaced the block with return 302 /$1 which would redirect the client to the expected path (e.g.
/two/foo.php->
/foo.php`)
Furthermore, if I put deny all;
on either of the last two location blocks, it blocks all of the affected requests (/two/*.php, /two/path/to/nonexistent.file)
It's like it's not stopping at the first fastcgi pass location block - am I missing something which should tell it to stop?
-
EDIT: Adding break;
did not stop, and trying to debug by adding headers in each location block only shows the header present in the last generic php block.
-
EDIT 2:
It turns out that fastcgi_split_path_info
needed changing to also account for the directory prefix.
So I've ripped out the snippet file and modified it a bit inside the location block:
location ^~ /two {
alias /data/srv/nginx/two.com/public/;
try_files $uri $uri/ /two/index.php$is_args$args;
location ~* ^\/two.+\.php$ { # have also tried with just \.php$
alias /srv/two.com/public/$1;
fastcgi_split_path_info ^/two(.+\.php)().*$; # the second group is deliberately empty.
try_files $fastcgi_script_name =404;
fastcgi_param PATH_INFO $path_info;
fastcgi_index index.php;
include snippets/fastcgi_params.conf;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/var/run/php/7.1-two.com.sock;
}
}
This seems to get the location blocks working, except when I traverse one level deeper e.g. /two/account
- which shows one.com's 404 page again.
I've dropped a deny on the outer location which stops the request, but dropping a deny on the inside location instead does not block the request. For some reason it decides to the use the last regex location in the original code.