NGINX: How to send all requests to a single file

Updated: January 20, 2024 By: Guest Contributor Post a comment

Introduction

NGINX is a powerful, open-source HTTP server known for its high performance, simple configuration, and low resource consumption. In certain circumstances, you might want your NGINX server to serve all incoming HTTP requests via a single PHP file or an HTML file. This could be for reasons such as application architecture, simplified routing, or for handling all requests using a front-controller pattern which is popular in modern web applications.

In this tutorial, we will explore how to configure NGINX to direct all requests to a single file. We will proceed with various examples starting from the basic configurations to more advanced settings.

Prerequisites

  • A server running NGINX
  • Basic understanding of NGINX configuration files
  • Access to the NGINX configuration file (usually located at /etc/nginx/nginx.conf or within the /etc/nginx/conf.d/ or /etc/nginx/sites-available/ directories.)
  • Text editor to edit NGINX configuration files (e.g., vi, nano)

Basic NGINX Configuration

First, let’s start with a straightforward NGINX configuration that redirects all requests to an index.html file. You can achieve this by editing the server block in your configuration file.

server {
  listen 80;
  server_name example.com;
  root /var/www/html;

  location / {
    try_files $uri $uri/ /index.html;
  }
}

The location / block catches all requests to the document root and checks if the requested URI or directory exists. If neither is found, NGINX serves the index.html file.

Sending all requests to a PHP file

For applications that use a single PHP entry point (e.g., index.php), you’ll need to set up NGINX to pass all requests to PHP-FPM. Here’s a simple configuration for doing this:

server {
  listen 80;
  server_name example.com;
  root /var/www/html;

  index index.php;

  location / {
    try_files $uri $uri/ /index.php?$query_string;
  }

  location ~ \.php$ {
    include snippets/fastcgi-php.conf;
    fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
  }
}

This configuration tells NGINX to try_files directive also ensures that existing static files are served directly.

Advanced Configuration for Single Entry Point

For a more advanced setup, such as a web application that relies on URL rewriting for pretty URLs, you might want all requests rerouted through index.php without including the query string in the URL. This setup assumes you’re using something akin to the following RewriteRule in a .htaccess file for Apache:

In NGINX, you can achieve the equivalent rewrite by using the following configuration:

server {
  ... 
  location / {
    try_files $uri $uri/ @rewrite;
  }

  location @rewrite {
    rewrite ^/(.*)$ /index.php last;
  }
  ...
}

The @rewrite named location serves as a custom internal location that implements the URL rewriting logic.

Handling 404 Errors with a Single File

Some applications require custom handling for 404 not found errors, redirecting to an entry script instead of showing the default NGINX 404 page. Here is how you can do that:

server {
  ...
  error_page 404 /index.php;
  ...
}

With this directive, any 404 error will now be handled by your index.php file, potentially allowing for custom error page logic within your application.

Security Considerations

When configuring your NGINX server to redirect all requests to a single file, it’s essential to consider the security implications.

  • Ensure your server is configured to deny access to sensitive files like .htaccess, .git, and configuration files.
  • Be wary of allowing the execution of arbitrary PHP files uploaded by users, which can be mitigated by strategic location blocks and try_files checks.

Conclusion

In this tutorial, we have covered how to configure NGINX to redirect all requests to a single file, whether that be a static HTML file or a dynamic PHP script. We have also discussed advanced configuration strategies for more complex URL rewriting requirements and security best practices. Remember, it’s essential to test your configurations in a safe, non-production environment before deploying live.