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.
Table of Contents
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.