File Not Found when running PHP with Nginx
Try another *fastcgi_param* something like
fastcgi_param SCRIPT_FILENAME /usr/share/nginx/html$fastcgi_script_name;
File not found nginx php-fpm
The error indicates that your SCRIPT_FILENAME
is incorrect. Your comment:
in the wordpress container it's at /var/www/html/index.php in the
nginx container it's at /app
suggests that nginx
and php-fpm
are seeing a different document root.
In which case, use:
fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;
NGinx / PHP 404 Not Found when redirecting away from main website
problem was the second /root/ as well as a missing
location / {
try_files $uri $uri/ /index.php?$query_string;
}
File not found with nginx and php
So I have trying to work on your Issue for last 3 days, to get a better and deeper understanding of FASTCGI. I put a logger between and NGINX and FPM, and that helped me better understand the interactions. Below is the config that I believe should work for you
Edit-1
Updated config after resolving issue on chat
upstream react {
server react:3000;
keepalive 8;
}
map $fastcgi_script_name $fastcgi_script_name_fcgi {
"~*/ajax/(?P<rest_url>.*)$" /$rest_url;
default $fastcgi_script_name;
}
map $request_uri $request_uri_fcgi {
"~*/ajax/(?P<rest_url>.*)$" /$rest_url;
default $request_uri;
}
map $document_uri $document_uri_fcgi {
"~*/ajax/(?P<rest_url>.*)$" /$rest_url;
default $document_uri_fcgi;
}
server {
listen 0.0.0.0:80;
server_name localhost;
location / {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://react;
proxy_redirect off;
}
location /ajax {
alias /var/www/public;
try_files $uri @php;
}
location @php {
fastcgi_split_path_info ^/ajax/(.+\.php)(/.+)$;
fastcgi_pass fpm:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_NAME /index.php;
fastcgi_param REQUEST_URI $request_uri_fcgi;
fastcgi_param DOCUMENT_URI $document_uri_fcgi;
fastcgi_param SCRIPT_FILENAME /var/www/public/index.php;
}
client_max_body_size 5m;
}
So the basic idea is to replace /ajax
from document_root
using the alias
directive. Then to override the request_uri
and other parameters so the correct urls reach the PHP code for route resolution.
Below is part of what my php script receives when I call http://vm/ajax/router.php?x=2
{
"COOKIES": null,
"GET": {
"x": "2"
},
"POST": [],
"REQUEST": {
"x": "2"
},
"HEADERS": null,
"SERVER": {
"HOME": "/var/www",
"SCRIPT_FILENAME": "/var/www/html/router.php",
"DOCUMENT_ROOT": "/var/www/html",
"DOCUMENT_URI": "/router.php",
"REQUEST_URI": "/router.php?x=2",
"SCRIPT_NAME": "/router.php",
"CONTENT_LENGTH": "",
"CONTENT_TYPE": "",
"REQUEST_METHOD": "GET",
"QUERY_STRING": "x=2",
"FCGI_ROLE": "RESPONDER",
"PHP_SELF": "/router.php",
"argv": [
"x=2"
],
"argc": 1
}
}
As you can see nothing gets /ajax
Nginx tryfiles fallback skipped for non-existant php file
This happens because priority of regex matching locations like location ~ \.php$ { ... }
is greater than prefix locations like location / { ... }
. An exact location selection algorithm decribed in the location
directve documentation:
A location can either be defined by a prefix string, or by a regular expression. Regular expressions are specified with the preceding “
~*
” modifier (for case-insensitive matching), or the “~
” modifier (for case-sensitive matching). To find location matching a given request, nginx first checks locations defined using the prefix strings (prefix locations). Among them, the location with the longest matching prefix is selected and remembered. Then regular expressions are checked, in the order of their appearance in the configuration file. The search of regular expressions terminates on the first match, and the corresponding configuration is used. If no match with a regular expression is found then the configuration of the prefix location remembered earlier is used....
If the longest matching prefix location has the “
^~
” modifier then regular expressions are not checked.Also, using the “
=
” modifier it is possible to define an exact match of URI and location. If an exact match is found, the search terminates. For example, if a “/
” request happens frequently, defining “location = /
” will speed up the processing of these requests, as search terminates right after the first comparison.
The above means than when you get a /fakepath.php
request, it's processing goes directly to the location ~ \.php { ... }
where you didn't have any try_files
directive. Error you've got is coming from PHP-FPM daemon response when you pass a non-existent file path to it via SCRIPT_FILENAME
FastCGI parameter. The most simple is to add another try_files
directive to the second location block:
location ~ \.php$ {
try_files $uri /index.php$is_args$args;
...
}
However due to try_files
directive behavior described here you'll be unable to set PATH_INFO
FastCGI parameter using your current config. I don't think you really need it for you PHP web app since with your regex PATH_INFO
will be always empty anyway (and if you really do, change your regex to \.php($|/)
like shown here and use a suggested workaround). The only modern software I know that is really using PATH_INFO
nowadays is the Craft CMS, most of them (including most popular like WordPress, Laravel Framework, etc.) relies on REQUEST_URI
FastCGI parameter instead. Most probably you can safely remove those fastcgi_split_path_info ^(.+\.php)(/.+)$;
and fastcgi_param PATH_INFO $fastcgi_path_info;
lines from your config (as I already said, using \.php$
regex with the location
directive those lines don't do anything anyway).
nginx 404 Not Found for php files
Per Richard Smith's reference, I figured out that I needed to include a nested location php tag:
location/wiki {
alias /var/www/mediawiki;
try_files $uri =404;
index index.html index.htm index.php;
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
}
}
and php files are served now.
Related Topics
Sending Messages from PHP to Node.Js
Curl_Exec Printing Results When I Don't Want To
Isset() Function Is Returning True Even When Item Is Not Set
How to Properly Display Chinese Characters in PHP
PHP File Uploads Doesnot Read $_Files['Image']
Comparing Bcrypt Hash Between PHP and Nodejs
Pdo Multiple Fetching of Same Query
How to Start a Get/Post/Put/Delete Request and Judge Request Type in PHP
Creating a Very Simple 1 Username/Password Login in PHP
PHP Loop: Add a Div Around Every Three Items Syntax
Is This a PHP Date() Bug, or Is There Something Wrong with My Code
Php: Possible to Automatically Get All Posted Data and Multiple Checkbox Unchecked
How to Check If an Entered Value Is Currency