'How can I make this nested location configuration use the correct path to call a php program?
I have setup nginx to allow users to have a user website (https://example.org/username
maps to /home/username/www
).
I want to allow my users to use php. Php is installed and working for a tld on the same server. I do not want to allow php generally on this server, just for specific configurations.
The configuration looks like this.
server {
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
server_name example.org;
root /var/sites/example.org;
access_log /var/log/nginx/example_org_access.log main;
access_log /var/log/nginx/example_org_access.log scripts;
error_log /var/log/nginx/example_org_error.log info;
location / {
try_files maintain.html /index.html @node;
}
location ~ ^/(.+?)(/.*)?$ {
alias /home/$1/www/$2;
index index.html index.htm;
autoindex on;
location ~ ^.+?\.php(/.*)?$ {
include fastcgi_params;
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
# By default, the variable PATH_INFO is not set under PHP-FPM
# But some apps need it. If you have a “Bad Request” error, double check this var!
# NOTE: the separate $path_info variable is required. For more details, see:
# https://trac.nginx.org/nginx/ticket/321
set $path_info $fastcgi_path_info;
fastcgi_param PATH_INFO $path_info;
fastcgi_param SCRIPT_FILENAME /home$realpath_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}
}
}
I also have the following log format.
log_format scripts 'fastcgi: $realpath_root/$fastcgi_script_name > $request';
which outputs
fastcgi: -//username/info.php > GET /username/info.php HTTP/2.0
The php-fpm log shows the following for the same request.
- - 27/Apr/2022:20:47:08 -0600 "GET /username/info.php" 404 - 0.154 2048 0.00%
And the error log dumps the following.
2022/04/27 20:47:08 [error] 915687#915687: *14 FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream, client: 0.0.0.0, server: example.org, request: "GET /username/info.php HTTP/2.0", upstream: "fastcgi://unix:/var/run/php-fpm/php-fpm.sock:", host: "example.org"
All this tells me I'm doing the nested location wrong, specifically the fastcgi_param SCRIPT_FILENAME /home$realpath_root$fastcgi_script_name;
line.
Changing that to fastcgi_param SCRIPT_FILENAME /home/$1/www/$fastcgi_script_name
or fastcgi_param SCRIPT_FILENAME /home/$1/www/$2
doesn't work ($1 and $2 don't seem to be carried into the nested configuration, which makes sense).
So, am I mistaken in the belief I can set this up this way? How can I make this work?
Solution 1:[1]
@Richard Smith's comment helped point me in the right direction. This configuration works.
server {
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
server_name example.com;
root /var/sites/example.com;
access_log /var/log/nginx/example_com_access.log main;
access_log /var/log/nginx/example_com_access.log scripts;
error_log /var/log/nginx/example_com_error.log info;
try_files index.html index.htm /index.html =404;
location ~ ^/(?<username>[^/]+?)(?<userpath>/.*)?$ {
alias /home/$username/www$userpath;
location ~ ^.+?\.php(?:/.*)?$ {
include fastcgi_params;
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
# By default, the variable PATH_INFO is not set under PHP-FPM
# But some apps need it. If you have a “Bad Request” error, double check this var!
# NOTE: the separate $path_info variable is required. For more details, see:
# https://trac.nginx.org/nginx/ticket/321
set $path_info $fastcgi_path_info;
fastcgi_param PATH_INFO $path_info;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | harleypig |