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?