I am using a simple nginx config for a single page application that serves static files and routes requests to index.php file. The issue with this config was discovered when I coded page visit logging system. What is happening: when try_files does not find a file, it still runs index.php, wasting resources on application initialization, connection to database, etc...
Basically, any request for a missing file triggers a @fallback. So how can I only rewrite to PHP for /page1, /page2/suburl, but not /favicon.ico?
Thank you
Config:
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/;
index index.php;
server_name _;
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
}
location /static {
expires 1y;
add_header Cache-Control "public";
access_log off;
}
location / {
try_files $uri $uri/ @fallback;
}
location @fallback {
#404 request for /favicon.ico still runs the index.php script
rewrite ^ /index.php;
add_header Cache-Control "no-store, no-cache, must-revalidate";
}
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
}
Edit: I have added the following fix, yet I want to accomplish this with nginx:
if (strpos($_SERVER['REQUEST_URI'], ".")) {
http_response_code(404);
return;
}
If you don't want to add some favicon.ico to your webserver root, you can add the following location to your nginx config:
location = /favicon.ico { return 404; }
If you don't have any routes with the dot character and you want to apply your fix at the nginx level, you can try the following (location blocks order matters since regex matching locations are checked from the first to the last one):
server {
...
location ~ \.php$ {
try_files $uri =404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
}
location ~ \. {
try_files $uri =404;
}
location ^~ /static/ {
expires 1y;
add_header Cache-Control "public";
access_log off;
}
...
}
The ^~
location modifier will make your config work faster making nginx skip regex matching over URIs started with /static/
(I'm assuming here you have no PHP files inside that directory).