nginx: multiple document roots with fastcgi
Solution 1
When you change roots, you need to set up a second location to pass to php:
server {
root /home/tman/dev/project/trunk/data;
index index.php;
# Use location ^~ to prevent regex locations from stealing requests
location ^~ /sqlbuddy {
root /srv/http;
# This location will handle requests containing .php within /sqlbuddy
# and will use the root set just above
location ~* \.php {
include fastcgi.conf;
fastcgi_pass 127.0.0.1:9000;
}
}
location ~* \.php {
include fastcgi.conf;
fastcgi_pass 127.0.0.1:9000;
}
}
Also, unless you're using path info-style urls like /index.php/foo/bar, you probably want to change .php to .php$ to anchor the match at the end of the uri.
Solution 2
The reason for this is Nginx will choose the "best" location
block:
Correct me if I'm wrong. Currently, Nginx doesn't support global setting for fastcgi. So, either you must re-define the fastcgi_pass
:
location /sqlbuddy {
root /srv/http;
index index.php;
}
location /sqlbuddy/.+\.php$ {
fastcgi_pass 127.0.0.1:9000;
include fastcgi.conf;
}
or you can check the $request_uri
with if
directive in the second location
:
location ~ \.php$ {
if ($request_uri ~ /sqlbuddy/.*$) {
root /srv/http;
}
fastcgi_pass 127.0.0.1:9000;
include fastcgi.conf;
}
Related videos on Youtube
tman
Updated on September 18, 2022Comments
-
tman almost 2 years
When using a single document root in my http directive, everything works fine. However, I want to add a location directive with an additional directive and I can't get fastcgi to work with this additional root (I receive a white page when accessing http://localhost/sqlbuddy).
Here's an excerpt of my nginx.conf:
server { root /home/tman/dev/project/trunk/data; index index.php; location /sqlbuddy { root /srv/http; index index.php; } location ~* \.php { fastcgi_pass 127.0.0.1:9000; include fastcgi.conf; } }
And my fastcgi.conf:
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param QUERY_STRING $query_string; fastcgi_param REQUEST_METHOD $request_method; fastcgi_param CONTENT_TYPE $content_type; fastcgi_param CONTENT_LENGTH $content_length; fastcgi_param SCRIPT_NAME $fastcgi_script_name; fastcgi_param REQUEST_URI $request_uri; fastcgi_param DOCUMENT_URI $document_uri; fastcgi_param DOCUMENT_ROOT $document_root; fastcgi_param SERVER_PROTOCOL $server_protocol; fastcgi_param GATEWAY_INTERFACE CGI/1.1; fastcgi_param SERVER_SOFTWARE nginx/$nginx_version; fastcgi_param REMOTE_ADDR $remote_addr; fastcgi_param REMOTE_PORT $remote_port; fastcgi_param SERVER_ADDR $server_addr; fastcgi_param SERVER_PORT $server_port; fastcgi_param SERVER_NAME $server_name; # PHP only, required if PHP was built with --enable-force-cgi-redirect fastcgi_param REDIRECT_STATUS 200;
Both nginx's error.log and php-fpm's log don't show any errors about it. I'd prefer not to put everything in the same document root.
-
Greg Petersen over 12 yearsPlease leave a comment to let me know why you down vote?
-
tman over 12 yearsI think you're answer is valid, but it didn't work for me (/sqlbuddy still served a white page). I think this is because it doesn't use ^~. in the location directive. kolbyjack's nested location directive solution worked fine for me though. Sorry I can't upvote this (not enough reputation yet).
-
DanO almost 12 yearsThe second solution worked perfectly for me. Especially if you use a PHP framework like Kohana with
try_files
! -
bufh almost 12 yearsThank you kolbyjack, your solution is clean and elegant.
-
berkus over 8 yearsThanks, in my case with rewrites the trick with
if
inside fastcgi location helped!