This morning I had a strange problem about finding php script files with Nginx and Php-fpm.
I solved it, but I didn't understand what the problem actually was.
Some details: I'm on Arch Linux and using PHP-FPM 7.3.9 and Nginx 1.16.1.
I wanted to try the Grav CMS, so I set up nginx and php-fpm as needed. What happened is that php-fpm couldn't find the index.php file, returning a 404 error.
My configuration files are pretty simple: I took the default ones and changed a couple of parameters.
My /etc/nginx/nginx.conf file is this one
user http;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
include sites-enabled/*;
}
It's Nginx's default one on Arch Linux where I removed an example server{} block (to include from enabled-sites as in Debian and others) and some comments.
And my configuration file for the specific Grav virtual server was
server {
#listen 80;
index index.html index.php;
## Begin - Server Info
root /home/MYUSERNAME/Desktop/grav;
server_name localhost;
## End - Server Info
## Begin - Index
# for subfolders, simply adjust:
# `location /subfolder {`
# and the rewrite to use `/subfolder/index.php`
location / {
try_files $uri $uri/ /index.php?$query_string;
}
## End - Index
## Begin - Security
# deny all direct access for these folders
location ~* /(\.git|cache|bin|logs|backup|tests)/.*$ { return 403; }
# deny running scripts inside core system folders
location ~* /(system|vendor)/.*\.(txt|xml|md|html|yaml|yml|php|pl|py|cgi|twig|sh|bat)$ { return 403; }
# deny running scripts inside user folder
location ~* /user/.*\.(txt|md|yaml|yml|php|pl|py|cgi|twig|sh|bat)$ { return 403; }
# deny access to specific files in the root folder
location ~ /(LICENSE\.txt|composer\.lock|composer\.json|nginx\.conf|web\.config|htaccess\.txt|\.htaccess) { return 403; }
## End - Security
## Begin - PHP
location ~ \.php$ {
# Choose either a socket or TCP/IP address
fastcgi_pass unix:/run/php-fpm/php-fpm.sock;
# fastcgi_pass unix:/var/run/php5-fpm.sock; #legacy
# fastcgi_pass 127.0.0.1:9000;
add_header x-full-path $document_root$fastcgi_script_name;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
## End - PHP
}
As you can notice from the comments, it is the default configuration file provided by Grav itself. You can check it out here.
I just edited the root directory and adjusted the socket path according to my php-fpm one.
I didn't touch any php-fpm configuration.
The result I was getting was "File not found." without any nginx reference. I already encountered that page before, and I knew it was php-fpm's error page.
Indeed, when I changed nginx's configuraton to point at some index.html it worked.
So I tried to check if it was a permission problem (but it seemed weird, I would have expected a different error message): I checked that both nginx and php-fpm were running as the same user (in this case 'http') and I changed the ownership and access mode as myusername:http 775 to give to both my user and http user every permission (I know it's not a good practice, but I was testing).
Still the same error.
I tried also to debug the parameters passed by nginx in the line
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
by commenting that line and adding a header with the value of the parameter.
The path was correct. I copy-pasted it on the terminal to see if there was any typo, but nope. Everything good.
I also tried to pass the absolute path of the index file to php-fpm (in the directive above) but nothing.
At this point I tried one last thing: I moved the 'grav' folder from my dekstop to /srv/http (which on Arch is the default folder in nginx configuration), and edited the nginx configuration files accordingly. The permissions are http:myusername 664 there.
And it worked.
So I started looking for anything that could've caused the error in php-fpm's configuration files.
I found out the chdir option in /etc/php/php-fpm.d/www.conf . The comment says
Chdir to this directory at the start. Note: relative path can be used. Default Value: current directory or / when chroot
Because I did not set chroot (I checked, it's the option above this in the file) it should be /.
But even if it looked for files from root, it makes no sense that it couldn't find the index, because I always passed absolute paths. I couldn't find anything on google about the way fpm intepretes paths according to chdir option.
So, the question is: what happened? Why did it work on one directory and not on another one?