Nginx: Laravel App in a Reverse Proxy, Preserve URL

reduced Nginx Reverse Proxy Larave

In this tutorial, we’ll explain how to access a remote Laravel 10 app through a reverse proxy, from an existing Nginx-hosted website.

Reverse proxies can be used to run a domain name on multiple servers. They can offer better isolation for projects that are not directly connected. It can spread the server load on multiple servers, or run demanding web apps on their own dedicated machines, without affecting the rest of the site.

Reverse proxies are better alternatives to using subdomains like https://myapp.example.com to run the apps on a remote server, as they preserve the domain name entirely.

 

Tutorial objective

The objective of this tutorial is to run a Laravel app hosted on Server B on a specific URL path of a WordPress site hosted on Server A, such as https://ServerAWordpress.com/app. The goal is to ensure that the URL of the WordPress site is preserved while using the proxied URL path. In addition, all resources of the Laravel app, including routes, must load correctly without any issues

Nginx Server Setup (before Proxy)

Nginx Server A – Runs a WordPress Site at https://ServerAWordpress.com

Nginx Server B – Runs a Laravel App at https://ServerBLaravel.com

Server A Starting Config File (WordPress)

server {
    server_name serverAWordpress.com www.serverAWordpress.site;
    listen 443 ssl;

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

    location = /favicon.ico {
        log_not_found off;
        access_log off;
    }

    location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
        expires max;
        log_not_found off;
    }

    location = /robots.txt {
        allow all;
        log_not_found off;
        access_log off;
    }

    location ~ \.php$ {
         include snippets/fastcgi-php.conf;
         fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
         fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
         include fastcgi_params;
    }
    ssl_certificate /etc/letsencrypt/live/ServerAWordpress.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/ServerAwordpress.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
}

server {
    if ($host = www.serverA.com) {
        return 301 https://$host$request_uri;
    }

    if ($host = serverA.com) {
        return 301 https://$host$request_uri;
    }

    listen 80;
    server_name serverAwordpress.com www.serverAwordpress.com;
    return 404;
}

Server B Starting Config File (Laravel)

server {
    server_name ServerBLaravel.com;
    root /var/www/html/laravelapp/public;

index index.php index.html;
    charset utf-8;


    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    error_page 404 /index.php;

    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/ServerBLaravel.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/ServerBLaravel.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}

Setting up the Nginx Reverse Proxy

Server A Config – Add Proxied Location

On Server A, we add a location for the proxied app and use proxy_pass. I’ll use the path /myapp/

server {
    server_name serverAWordpress.com www.serverAWordpress.com;

    location /myapp/ {
        proxy_pass https://serverBLaravel.com/myapp/; #address of the remote server
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
.....

Server B Config – Location & CORS Headers

In order to preserve the Domain and URL Path of Server A, add a location /myapp/ the Nginx config.

This will tell Laravel to run in the /myapp/ path.

    location /myapp/ { try_files $uri $uri/ @myapp; } 
    location @myapp { rewrite ^/myapp/(.*)$ /index.php?/$1 last; }

To access Laravel’s javascript resources from Server A’s proxy, add Cross-Origin Resource Sharing (CORS) headers.

# CORS headers
   add_header 'Access-Control-Allow-Origin' 'https://serverAWordpress.com';
   add_header 'Access-Control-Allow-Credentials' 'true';
   add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
   add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
   add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';

  # Cache settings
   expires 30d;
   add_header Pragma public;
   add_header Cache-Control "public";

Laravel .env Setup

Set the APP_URL and ASSET_URL variables.

APP_URL=https://serverblaravel.com/myapp/
ASSET_URL=https://serverblaravel.com    // lets laravel know where to look for the resources

Laravel Routes

Because we configured Nginx to run the app on the /myapp/ location, we need to add the /myapp/ to all the routes in /routes/web.php

Route::get('/myapp/', function () {
    return Inertia::render('Welcome'); #i'm using inertia for this example app, but it has no impact on the reverse proxy.
});

If you have hard-coded paths in your Javascript components, make sure to also update them to the new path, and rebuild your code with npm run build

Restart Nginx and Test the Proxied Path

Run on both servers:

nginx -t && systemctl restart nginx

If no errors are displayed, you can go ahead and open the proxied URL pathhttps://serverAWordpress.com/myapp/.

The Laravel App should now be from the WordPress server.

Conclusion

In conclusion, using a reverse proxy can be a great solution for running demanding web apps on dedicated machines without affecting the rest of the site. In this tutorial, we learned how to access a remote Laravel 10 app through a reverse proxy, from an existing Nginx-hosted website. We explored the steps involved in setting up the Nginx reverse proxy and configuring both the Nginx and Laravel servers to work together seamlessly. By following the steps outlined in this tutorial, you should now be able to run your Laravel app on a remote server while preserving the domain name entirely.

0 Shares:
Subscribe
Notify of
guest
Receive notifications when your comment receives a reply. (Optional)
Your username will link to your website. (Optional)

0 Comments
Inline Feedbacks
View all comments
You May Also Like