How to Set Up Virtual Hosts on Nginx

Summary: Serve multiple Laravel apps using Nginx server blocks.


Managing multiple Laravel applications on a single server can be streamlined and efficient using Nginx virtual hosts, also known as server blocks. This approach lets you serve different websites or web apps using unique domain names, all from the same Nginx instance. In this guide, you’ll learn how to set up Nginx server blocks to host multiple Laravel apps under separate domains.


Prerequisites

  • A Linux server (e.g., Ubuntu 20.04+)
  • Nginx installed (sudo apt install nginx)
  • Multiple Laravel apps deployed on the server, each in separate directories
  • Domain names pointing to your server's public IP (use /etc/hosts for testing locally)
  • Basic command-line proficiency and sudo privileges

1. Directory Structure

Suppose you have:

  • Laravel App 1 at /var/www/laravel-app1
  • Laravel App 2 at /var/www/laravel-app2

Each app is expected to have the default Laravel folder structure, with the document root inside the public folder.


2. Creating Nginx Server Blocks

Nginx server blocks allow you to run multiple websites on a single server instance. Each website has its own server block configuration.

Step 1: Create Server Block Configuration Files

We'll create one config file per app:

sudo nano /etc/nginx/sites-available/app1.example.com
sudo nano /etc/nginx/sites-available/app2.example.com

Example: Configuration for app1.example.com

server {
    listen 80;
    server_name app1.example.com;

    root /var/www/laravel-app1/public;

    index index.php index.html;

    access_log /var/log/nginx/app1_access.log;
    error_log /var/log/nginx/app1_error.log;

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

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php8.2-fpm.sock; # Adjust PHP version if needed
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.ht {
        deny all;
    }
}

Change paths, domain, and PHP version as needed.

Duplicate and modify for App 2

Copy and modify for each Laravel app, matching the domain and root path:

server {
    listen 80;
    server_name app2.example.com;

    root /var/www/laravel-app2/public;

    index index.php index.html;
    access_log /var/log/nginx/app2_access.log;
    error_log /var/log/nginx/app2_error.log;

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

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.ht {
        deny all;
    }
}

Step 2: Enable the Server Blocks

Create symbolic links to the sites-enabled directory:

sudo ln -s /etc/nginx/sites-available/app1.example.com /etc/nginx/sites-enabled/
sudo ln -s /etc/nginx/sites-available/app2.example.com /etc/nginx/sites-enabled/

Step 3: Test and Reload Nginx

Check the configuration syntax:

sudo nginx -t

If no errors are reported, reload Nginx to apply changes:

sudo systemctl reload nginx

3. Update DNS or /etc/hosts

For the domains to work, they must resolve to your server’s public IP. If you’re testing locally, add these lines to your /etc/hosts file:

127.0.0.1   app1.example.com
127.0.0.1   app2.example.com

If the domains are live, update your DNS records accordingly.


4. Set Permissions

Laravel apps require proper permissions on storage and bootstrap/cache:

sudo chown -R www-data:www-data /var/www/laravel-app1/storage /var/www/laravel-app1/bootstrap/cache
sudo chown -R www-data:www-data /var/www/laravel-app2/storage /var/www/laravel-app2/bootstrap/cache
sudo find /var/www/laravel-app1/storage -type d -exec chmod 775 {} \;
sudo find /var/www/laravel-app2/storage -type d -exec chmod 775 {} \;

5. (Optional) Enable HTTPS

For production, use Let’s Encrypt to add SSL to each domain:

sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d app1.example.com
sudo certbot --nginx -d app2.example.com

Conclusion

By setting up Nginx server blocks, you can efficiently serve multiple Laravel applications on your server, each with its own configuration and domain. This approach is scalable and maintainable, making it an industry best practice for multi-site hosting with Nginx.

Did you find this guide helpful? Let us know or share your tips for managing multiple Laravel apps on one server!