Hosting Multiple Projects on a Single Domain with Nginx

Understanding Location Block Matching

The location directive determines how Nginx processes request URIs. The matching process follows a specific priority order rather than a simple sequential check:

  1. Exact Match (=): If the URI matches exactly, the search stops immediately, and this block is used. This is the highest priority.
  2. Priority Prefix Match (^~): If the URI starts with the specified string, the search stops. Crucially, this halts the evaluation of regular expressions, making it efficient for specific path prefixes.
  3. Regular Expression Matches (~ and ~*): These are evaluated in the order they appear in the configuraton file. The first match wins. ~ is case-sensitive, while ~* is case-insensitive.
  4. Longest Prefix Match: If no exact or priority matches are found, and no regular expression matches, Nginx uses the longest matching prefix string.

Key Distinctions:

  • Standard prefix matching (no modifier) will still allow regular expression checks to override it if a regex match is found later.
  • The ^~ modifier is distinct because it prevents regex evaluation if a prefix match occurs.

Modifier Syntax Reference

  • =: Exact match. The request URI must match the path perfectly. ``` location = /dashboard { ... }

  • ^~: Prefix match that takes priority over regular expressions. ``` location ^~ /images/ { ... }

  • ~: Case-sensitive regular expression match. ``` location ~ .php$ { ... }

  • ~*: Case-insensitive regular expression match. ``` location ~* .(gif|jpg|png)$ { ... }

  • No Modifier: Standard prefix match, evaluated after regex. ``` location /blog/ { ... }

  • /: Default match for any request not matched by other locations. ``` location / { ... }

    
    

Configuration Example

The following configuration demonstrates how to serve two distinct projects (portal and admin) from a single domain. We use the ^~ modifier to ensure the path routing takes precedence.

server {
    listen       80;
    server_name  demo.example.com;
    root         /var/www/default;
    index        index.html index.htm;

    access_log   /var/log/nginx/demo.access.log main;

    # Project 1: Portal Application
    # Matches requests starting with /portal/
    location ^~ /portal/ {
        alias /var/www/projects/portal/public/;
        try_files $uri $uri/ /portal/index.html;
    }

    # Project 2: Admin Dashboard
    # Matches requests starting with /admin/
    location ^~ /admin/ {
        alias /var/www/projects/admin/public/;
        try_files $uri $uri/ /admin/index.html;
    }

    # PHP handling for specific scripts (if needed)
    location ~ \.php$ {
        fastcgi_pass   unix:/run/php/php-fpm.sock;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }

    # Error handling
    error_page 404 /404.html;
    error_page 500 502 503 504 /50x.html;

    location = /50x.html {
        root /usr/share/nginx/html;
    }
}

Tags: nginx reverse proxy Server Configuration Location Block devops

Posted on Mon, 05 Oct 2026 16:39:40 +0000 by renj0806