So your location should look like (wrong example! see the update to answer)
So your location should look like
So your location should look like (wrong example! see the update to answer)
Update @ 2025.01.22
It turns out that two of the three configuration variants where the try_files directive was being used, contain mistakes regarding the usage of this directive.
The variant I proposed:
try_files /dev/null /index.php$is_args$args; will result in an internal redirection loop. Additionally, using /dev/null as the first parameter of the try_files directive offers no performance benefit, contrary to what is suggested here.
The variant proposed by @TeroKilkanen:
try_files /index.php$is_args$args =404; is closer to being correct. However, the $is_args and $args nginx variables should not be used in this context because they will be treated as part of the physical filename rather than the query string. Consequently, any request with a query string will fail with this configuration.
Moreover, the snippets/fastcgi-php.conf file (a configuration snippet packaged with nginx on Debian-based Linux distributions) contains the following:
# regex to split $uri to $fastcgi_script_name and $fastcgi_path fastcgi_split_path_info ^(.+\.php)(/.+)$; # Check that the PHP script exists before passing it try_files $fastcgi_script_name =404; # Bypass the fact that try_files resets $fastcgi_path_info # see: http://trac.nginx.org/nginx/ticket/321 set $path_info $fastcgi_path_info; fastcgi_param PATH_INFO $path_info; fastcgi_index index.php; include fastcgi.conf; If this snippet is included in the PHP location block that already contains a try_files directive, it will cause the following error during configuration validation at nginx startup:
nginx: [emerg] "try_files" directive is duplicate in ... That being said, there are two correct options to achieve the behavior the OP desires:
- Using the
try_filesdirective to additionally check an existence of theindex.phpfile:location / { try_files /index.php =404; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $request_filename; fastcgi_pass unix://var/run/php/php7.3-fpm.sock; } - Skip the existence check for better performance explicitly specifying the PHP script filename (if you are certain that the
index.phpfile always exists):
Or even explicitly specifying the full path to thelocation / { include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root/index.php; fastcgi_pass unix://var/run/php/php7.3-fpm.sock; }index.phpfile (this way therootdirective can be omitted al all):location / { include fastcgi_params; fastcgi_param SCRIPT_FILENAME /full/path/to/index.php; fastcgi_pass unix://var/run/php/php7.3-fpm.sock; }
Update @ 2025.01.22
It turns out that two of the three configuration variants where the try_files directive was being used, contain mistakes regarding the usage of this directive.
The variant I proposed:
try_files /dev/null /index.php$is_args$args; will result in an internal redirection loop. Additionally, using /dev/null as the first parameter of the try_files directive offers no performance benefit, contrary to what is suggested here.
The variant proposed by @TeroKilkanen:
try_files /index.php$is_args$args =404; is closer to being correct. However, the $is_args and $args nginx variables should not be used in this context because they will be treated as part of the physical filename rather than the query string. Consequently, any request with a query string will fail with this configuration.
Moreover, the snippets/fastcgi-php.conf file (a configuration snippet packaged with nginx on Debian-based Linux distributions) contains the following:
# regex to split $uri to $fastcgi_script_name and $fastcgi_path fastcgi_split_path_info ^(.+\.php)(/.+)$; # Check that the PHP script exists before passing it try_files $fastcgi_script_name =404; # Bypass the fact that try_files resets $fastcgi_path_info # see: http://trac.nginx.org/nginx/ticket/321 set $path_info $fastcgi_path_info; fastcgi_param PATH_INFO $path_info; fastcgi_index index.php; include fastcgi.conf; If this snippet is included in the PHP location block that already contains a try_files directive, it will cause the following error during configuration validation at nginx startup:
nginx: [emerg] "try_files" directive is duplicate in ... That being said, there are two correct options to achieve the behavior the OP desires:
- Using the
try_filesdirective to additionally check an existence of theindex.phpfile:location / { try_files /index.php =404; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $request_filename; fastcgi_pass unix://var/run/php/php7.3-fpm.sock; } - Skip the existence check for better performance explicitly specifying the PHP script filename (if you are certain that the
index.phpfile always exists):
Or even explicitly specifying the full path to thelocation / { include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root/index.php; fastcgi_pass unix://var/run/php/php7.3-fpm.sock; }index.phpfile (this way therootdirective can be omitted al all):location / { include fastcgi_params; fastcgi_param SCRIPT_FILENAME /full/path/to/index.php; fastcgi_pass unix://var/run/php/php7.3-fpm.sock; }
- Location you used will match only the requests containing
$symbol, that's definitely not what you want. - Using the
try_filesdirective you must specify at least one file/folder to check. The easiest way to specify the file that would fail the existence check is to specifydev/null.
So your location should look like
location / { try_files /dev/null /index.php$is_args$args; include snippets/fastcgi-.conf; fastcgi_param SCRIPT_FILENAME $request_filename; fastcgi_pass unix://var/run/php/php7.3-fpm.sock; } or, without the try_files directive
location / { include fastcgi.conf; fastcgi_param SCRIPT_FILENAME $document_root/index.php; fastcgi_pass unix://var/run/php/php7.3-fpm.sock; } - Location you used will match only the requests containing
$symbol, that's definitely not what you want. - Using the
try_filesdirective you must specify at least one file/folder to check. The easiest way to specify the file that would fail the existence check is to specifydev/null.
So your location should look like
location / { try_files /dev/null /index.php$is_args$args; include snippets/fastcgi-php.conf; fastcgi_pass unix://var/run/php/php7.3-fpm.sock; } - Location you used will match only the requests containing
$symbol, that's definitely not what you want. - Using the
try_filesdirective you must specify at least one file/folder to check. The easiest way to specify the file that would fail the existence check is to specifydev/null.
So your location should look like
location / { try_files /dev/null /index.php$is_args$args; include fastcgi.conf; fastcgi_param SCRIPT_FILENAME $request_filename; fastcgi_pass unix://var/run/php/php7.3-fpm.sock; } or, without the try_files directive
location / { include fastcgi.conf; fastcgi_param SCRIPT_FILENAME $document_root/index.php; fastcgi_pass unix://var/run/php/php7.3-fpm.sock; }