Setting Up Ratals on Nginx (Complete Configuration Guide)

Rob Cuppett Author: Rob Cuppett

If you're installing Ratals on a Nginx server, there's one important step you cannot skip: configuring your Nginx server correctly.

Unlike Apache, Nginx does not use .htaccess files, which means rewrite rules and routing must be defined manually in your server configuration.

This guide walks you through:

  1. Understand the Configuration
  2. Update Required Values (IMPORTANT)
  3. Apply the Configuration via SSH
  4. Test Your Nginx Configuration Before Restarting
  5. Restart Services
  6. Final Notes
  7. You're Done
  8. Troubleshooting: Admin Not Loading After Installation

Step 1: Understand the Configuration

Below is a full Nginx configuration template for Ratals.

Before applying this to your server, review the required updates in Step 2 and create a backup of your current configuration in case you need to revert.

Nginx Configuration Template

server {
    # LISTEN PORT
    # Accept incoming HTTP traffic on IPv4 and IPv6
    listen 80 default_server;
    listen [::]:80 default_server;
    
    # ROOT DIRECTORY (UPDATE IF NEEDED)
    # This is where your website files live
    root /var/www/html;
    
    # DEFAULT INDEX FILES
    # Priority order when loading a directory
    index index.php index.html index.htm;
    
    # Catch-all server name
    server_name _;
    
    # Allows Nginx to accept 512MB uploads
    client_max_body_size 512M;
    
    ############################################################
    # IMPORTANT:
    # The public admin URL (/YOUR_ADMIN_URL_PATH/) is a virtual path.
    # All requests are internally rewritten to /admin/, while direct access
    # to /admin/ is blocked for security.
    #
    # The /admin/ directory still exists on the server, but is intentionally
    # blocked from direct public access. Only the virtual path should be used.
    #
    # Replace "YOUR_ADMIN_URL_PATH" everywhere below (e.g., secret-login)
    #
    # Example:
    # https://ratals.com/secret-login/
    # Replace "YOUR_ADMIN_URL_PATH" everywhere below with: secret-login
    ############################################################
    
    ############################################################
    # IMPORTANT:
    # Replace "include snippets/fastcgi-php.conf;" and "fastcgi_pass unix:/run/php/php8.2-fpm.sock;"
    # with your correct include path location and PHP version in the socket.
    ############################################################
    
    ############################################################
    # IMPORTANT:
    # If you change your admin virtual URL inside Ratals admin area,
    # you must update it here as well.
    ############################################################
    
    # Enable gzip compression for better performance
    gzip on;
    gzip_types text/plain text/css text/xml application/xml application/json application/javascript image/svg+xml;
    
    # CACHE CONTROL
    # Cache static assets for 1 year (EXCEPT admin + virtual admin path)
    # Improves performance by reducing repeat requests
    location ~* ^/(?!admin/|YOUR_ADMIN_URL_PATH/).*\.(jpg|jpeg|png|gif|svg|ico|webp|avif|bmp|css|js|woff|woff2|ttf|otf|eot)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }
    
    # Block access to hidden config files
    location ~* (\.htaccess|\.user\.ini)$ {
        deny all;
    }
    
    # Protect core system directories from public access
    location ~* ^/(core|hooks|storage)(/|$) {
        deny all;
    }
    
    # Redirect /YOUR_ADMIN_URL_PATH to /YOUR_ADMIN_URL_PATH/
    # Ensures consistent trailing slash behavior
    location = /YOUR_ADMIN_URL_PATH {
        return 301 /YOUR_ADMIN_URL_PATH/;
    }
    
    # BLOCK DIRECT ACCESS TO REAL ADMIN MODULES
    # Prevents users from bypassing the virtual admin path
    location ~* ^/admin/(cms|commerce|erp|ai)(/|$) {
        deny all;
    }
    
    ############################################################
    # --- VIRTUAL PATH HANDLER (/admin/) ---
    ############################################################
    # Maps the public virtual admin path to the real /admin/ directory
    
    # IMPORTANT ORDER NOTE:
    # Nginx processes location blocks based on prefix and regex priority.
    # More specific rules must come before general catch-all rules.
    
    # NOTE:
    # These routes are intentionally explicit instead of grouped,
    # to ensure correct handling and priority for each module.
    
    # 1. NOTICES & UPDATES
    location ^~ /YOUR_ADMIN_URL_PATH/cms/includes/notices/ {
        if ($uri !~* /notices/(ajax|start-update|update|update-progress|unset-progress-session)\.php$) {
            return 403;
        }
        
        rewrite ^/YOUR_ADMIN_URL_PATH/(.*)$ /admin/$1 break;
        fastcgi_param SCRIPT_FILENAME $document_root$uri;
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
    }
    
    # 2. CMS AJAX & FIELDS
    location ^~ /YOUR_ADMIN_URL_PATH/cms/includes/admin-fields/ajax/ {
        location ~ \.php$ {
            rewrite ^/YOUR_ADMIN_URL_PATH/(.*)$ /admin/$1 break;
            fastcgi_param SCRIPT_FILENAME $document_root$uri;
            include snippets/fastcgi-php.conf;
            fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        }
        rewrite ^/YOUR_ADMIN_URL_PATH/(.*)$ /admin/$1 break;
    }
    
    # 3. CMS LAYOUTS (STATIC & TABLE)
    # Handles layout rendering via AJAX (static + table layouts)
    location ^~ /YOUR_ADMIN_URL_PATH/cms/layouts/static/ajax/ {
        location ~ \.php$ {
            rewrite ^/YOUR_ADMIN_URL_PATH/(.*)$ /admin/$1 break;
            fastcgi_param SCRIPT_FILENAME $document_root$uri;
            include snippets/fastcgi-php.conf;
            fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        }
        rewrite ^/YOUR_ADMIN_URL_PATH/(.*)$ /admin/$1 break;
    }
    location ^~ /YOUR_ADMIN_URL_PATH/cms/layouts/table/ajax/ {
        location ~ \.php$ {
            rewrite ^/YOUR_ADMIN_URL_PATH/(.*)$ /admin/$1 break;
            fastcgi_param SCRIPT_FILENAME $document_root$uri;
            include snippets/fastcgi-php.conf;
            fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        }
        rewrite ^/YOUR_ADMIN_URL_PATH/(.*)$ /admin/$1 break;
    }
    
    # 4. COMMERCE LAYOUTS
    # Same concept as CMS, but for commerce module
    location ^~ /YOUR_ADMIN_URL_PATH/commerce/layouts/static/ajax/ {
        location ~ \.php$ {
            rewrite ^/YOUR_ADMIN_URL_PATH/(.*)$ /admin/$1 break;
            fastcgi_param SCRIPT_FILENAME $document_root$uri;
            include snippets/fastcgi-php.conf;
            fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        }
        rewrite ^/YOUR_ADMIN_URL_PATH/(.*)$ /admin/$1 break;
    }
    location ^~ /YOUR_ADMIN_URL_PATH/commerce/layouts/table/ajax/ {
        location ~ \.php$ {
            rewrite ^/YOUR_ADMIN_URL_PATH/(.*)$ /admin/$1 break;
            fastcgi_param SCRIPT_FILENAME $document_root$uri;
            include snippets/fastcgi-php.conf;
            fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        }
        rewrite ^/YOUR_ADMIN_URL_PATH/(.*)$ /admin/$1 break;
    }
    
    # 5. ERP AJAX & LAYOUTS
    # Handles ERP backend AJAX requests and UI rendering
    location ^~ /YOUR_ADMIN_URL_PATH/erp/includes/admin-fields/ajax/ {
        location ~ \.php$ {
            rewrite ^/YOUR_ADMIN_URL_PATH/(.*)$ /admin/$1 break;
            fastcgi_param SCRIPT_FILENAME $document_root$uri;
            include snippets/fastcgi-php.conf;
            fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        }
        rewrite ^/YOUR_ADMIN_URL_PATH/(.*)$ /admin/$1 break;
    }
    location ^~ /YOUR_ADMIN_URL_PATH/erp/layouts/static/ajax/ {
        location ~ \.php$ {
            rewrite ^/YOUR_ADMIN_URL_PATH/(.*)$ /admin/$1 break;
            fastcgi_param SCRIPT_FILENAME $document_root$uri;
            include snippets/fastcgi-php.conf;
            fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        }
        rewrite ^/YOUR_ADMIN_URL_PATH/(.*)$ /admin/$1 break;
    }
    location ^~ /YOUR_ADMIN_URL_PATH/erp/layouts/table/ajax/ {
        location ~ \.php$ {
            rewrite ^/YOUR_ADMIN_URL_PATH/(.*)$ /admin/$1 break;
            fastcgi_param SCRIPT_FILENAME $document_root$uri;
            include snippets/fastcgi-php.conf;
            fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        }
        rewrite ^/YOUR_ADMIN_URL_PATH/(.*)$ /admin/$1 break;
    }
    
    # 6. STANDALONE FILES (High Priority)
    # These are specific files that MUST bypass normal routing and be handled directly.
    # Using ^~ ensures these rules take priority over regex location blocks (~* below).
    
    # Media popup handler (AJAX endpoint used by CMS media manager)
    location ^~ /YOUR_ADMIN_URL_PATH/cms/includes/media-popup-ajax.php {
        location ~ \.php$ {
            rewrite ^/YOUR_ADMIN_URL_PATH/(.*)$ /admin/$1 break;
            fastcgi_param SCRIPT_FILENAME $document_root$uri;
            include snippets/fastcgi-php.conf;
            fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        }
        rewrite ^/YOUR_ADMIN_URL_PATH/(.*)$ /admin/$1 break;
    }
    
    # Editor JS asset (served as static file, no PHP needed)
    location ^~ /YOUR_ADMIN_URL_PATH/cms/includes/editor/editor.js {
        rewrite ^/YOUR_ADMIN_URL_PATH/(.*)$ /admin/$1 break;
    }
    
    # Editor CSS asset (served as static file, no PHP needed)
    location ^~ /YOUR_ADMIN_URL_PATH/cms/includes/stylesheet.css {
        rewrite ^/YOUR_ADMIN_URL_PATH/(.*)$ /admin/$1 break;
    }
    
    ############################################################
    # 7. ALLOW STATIC ASSETS FOR YOUR_ADMIN_URL_PATH
    ############################################################
    location ~* ^/YOUR_ADMIN_URL_PATH/.*\.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2|ttf|otf)$ {
        rewrite ^/YOUR_ADMIN_URL_PATH/(.*)$ /admin/$1 break;
    }
    
    ############################################################
    # 8. THE BLOCK - Security Catch-All
    ############################################################
    # Blocks any direct access to sensitive module directories through the virtual path.
    # Only explicitly allowed endpoints above will work.
    # Everything else inside cms/commerce/erp/ai is denied.
    location ~* ^/YOUR_ADMIN_URL_PATH/(cms|commerce|erp|ai|temp_extract)/ {
        deny all;
    }
    
    ############################################################
    # 9. GENERAL ADMIN NAVIGATION
    ############################################################
    # Catch-all handler for the virtual admin path.
    # This powers login, dashboard, and all normal admin page navigation.
    # Uses "last" so Nginx re-processes the rewritten URI through location matching again.
    location ^~ /YOUR_ADMIN_URL_PATH/ {
        rewrite ^/YOUR_ADMIN_URL_PATH/(.*)$ /admin/$1 last;
    }
    
    ############################################################
    # GENERAL ROUTING & PHP
    ############################################################
    
    # PHP Handler (global)
    # Any .php file that reaches this point gets executed by PHP-FPM.
    # Make sure the ALL socket + PHP version match your server setup.
    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
    }
    
    ############################################################
    # CORE ROUTING
    ############################################################
    
    # Admin routing (real /admin/ directory)
    # Falls back to /admin/index.php for framework-style routing
    location /admin/ {
       try_files $uri $uri/ /admin/index.php?$query_string;
    }
    
    # Main site routing
    # Standard front-controller pattern
    # If file/folder doesn't exist → route to index.php
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
}

Step 2: Update Required Values (IMPORTANT)

Before using this configuration, you must update the following values. Do this first so nothing is missed.

The config uses color highlighting to make this easy:

  • Yellow highlights = Values used in multiple places (must update ALL instances)
  • Blue highlights = PHP configuration values (must match your server setup)

1. Admin URL Path (Required)

Find and replace:

YOUR_ADMIN_URL_PATH

Replace it with your custom admin path that you have chosen to use when logging into your admin area.

Example:

https://www.ratals.com/secret-login/

Replace with:

secret-login

This appears in many places - you must update every instance.

Why this matters:

  • Secures your admin area (not using default /admin)
  • Ensures routing works correctly
  • Prevents broken admin pages and login issues

2. PHP Configuration (Required)

Update these lines to match your server:

include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
  • Update the PHP version if needed (e.g. php8.1, php8.3)
  • Update the socket include path if your server uses a different location

These also appear in multiple locations - update them all.

3. Root Directory

Set your correct project path:

/var/www/html

Update this if your project is located elsewhere.

4. Server Name

Update this if needed:

server_name _;

Replace _ with your domain if your server requires it.

Final Check Before Moving On

  • All YOUR_ADMIN_URL_PATH values updated
  • All PHP config values updated
  • Root directory is correct
  • Server name is correct (if required)

If even one of these is missed, parts of your site or admin may not work correctly.

Step 3: Apply the Configuration via SSH

Once your file is ready, connect to your server via SSH and follow these steps.

1. Open your Nginx config file for the site you are editing

You may need to update this path depending on your server setup. If you're not using the default site, make sure you're editing the correct configuration file for your domain.

nano /etc/nginx/sites-available/default

Tip: If you're unsure which file is being used, check your Nginx configuration or look inside the sites-enabled directory to see which config is active.

2. Paste your configuration

  • Replace the existing contents with your updated config
  • Make sure all required values from Step 2 are updated before saving

3. Save and exit:

CTRL + O is how you Save (Write Out)
Press Enter to confirm the save
CTRL + X to Exit the nano edit screen

Step 4: Test Your Nginx Configuration Before Restarting

Before restarting anything, always test:

sudo nginx -t

If everything is correct, you'll see a success message.

Step 5: Restart Services

Apply your changes by restarting PHP and Nginx:

sudo systemctl restart php8.2-fpm
sudo systemctl restart nginx

Important: Make sure the PHP version matches your server setup.

If you're using a different PHP version, update the command accordingly:

  • php8.1-fpm
  • php8.2-fpm
  • php8.3-fpm

If you're unsure which version you're running, you can check with:

php -v

Final Notes

  • If something doesn't load correctly, it's usually:
    • Missing or incorrect YOUR_ADMIN_URL_PATH
    • Incorrect PHP socket path (php8.2-fpm.sock)
    • Wrong root directory
  • Nginx is strict - even a small typo can break the config, so always run:
    sudo nginx -t
  • The /admin/ directory is intentionally blocked - always use your custom admin path

You're Done

Once everything is configured and restarted:

  1. Go back to your Ratals install page
  2. Refresh the page - the Nginx message will still appear, which is expected
  3. Continue the installation
  4. Important: Enter the same admin URL path you configured here during installation

If these do not match exactly, your admin area will not work correctly.

Troubleshooting: Admin Not Loading After Installation

This section only applies if you have already completed the installation and later changed your Nginx configuration.

If you update the admin URL path in this Nginx configuration before updating it inside the Ratals admin settings, the admin area will no longer load. This is expected behavior because the routing will no longer match.

This is not a system error - it simply means the configuration and database are no longer using the same admin path.

If this happens, you can restore access by updating the value directly in your database:

  • Database: your_database_name
  • Table: sites
  • Field: admin_directory

Important: If you have multiple sites in your database, make sure you update the admin_directory value for all sites/rows in the sites table.

Once these values match your Nginx configuration, your admin area will load normally.

Rob Cuppett
About the Author
Rob Cuppett is the founder and lead engineer behind Ratals, bringing over 20 years of experience in digital marketing, software development, and business automation. He shares expert tutorials, practical guides, and insights to help business owners optimize, customize, and fully leverage software solutions to grow their businesses efficiently.
0 Comments
Post a New Comment
This site uses cookies to deliver its services and to analyze traffic. Learn more on our Cookie Policy and Privacy Policy.