Nginx Reverse Proxy: Multiple Domains on a Single Server

Nginx Reverse Proxy: Multiple Domains on a Single Server

Manage multiple domains on a single server with Nginx reverse proxy. Server block configuration, SSL certificate, and upstream settings guide.

Renting a separate server for each project is both costly and inefficient in terms of management. With Nginx reverse proxy, you can route multiple domains to different applications (Node.js, PHP, Python) on a single server, manage SSL certificates centrally, and perform basic load balancing. In this guide, we cover Nginx reverse proxy setup from scratch, server block configuration, and Let's Encrypt SSL integration.

What Is a Reverse Proxy?

A reverse proxy is an intermediary that sits between the client (browser) and the backend application servers. The client doesn't connect directly to the application; Nginx receives the incoming request, decides which application to route it to, and returns the response to the client.

  • Single IP, multiple domains Nginx routes requests coming through the same IP to different applications by examining the Host header.
  • SSL termination SSL/TLS encryption and decryption is handled at Nginx; backend applications run on HTTP, which simplifies configuration.
  • Security layer Backend applications are not directly exposed to the internet. Nginx can perform rate limiting, IP restriction, and header filtering.

Nginx Installation and Basic Configuration

terminal - nginx installation
# Install Nginx (Ubuntu/Debian)
sudo apt update
sudo apt install nginx -y

# Start and enable the service
sudo systemctl enable --now nginx

# Open HTTP and HTTPS in the firewall
sudo ufw allow 'Nginx Full'

# Test configuration
sudo nginx -t

Managing Multiple Domains with Server Blocks

Create a separate server block file for each domain. Nginx selects the correct server block by examining the Host header of the incoming request.

Example 1: Node.js Application (port 3000)

/etc/nginx/sites-available/app1.example.com
server {
    listen 80;
    server_name app1.example.com;

    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        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;
        proxy_cache_bypass $http_upgrade;
    }
}

Example 2: PHP Application (WordPress)

/etc/nginx/sites-available/blog.example.com
server {
    listen 80;
    server_name blog.example.com;
    root /var/www/blog;
    index index.php index.html;

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

    location ~ \.php$ {
        fastcgi_pass unix:/run/php/php8.3-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}
terminal - enabling sites
# Enable sites
sudo ln -s /etc/nginx/sites-available/app1.example.com /etc/nginx/sites-enabled/
sudo ln -s /etc/nginx/sites-available/blog.example.com /etc/nginx/sites-enabled/

# Test configuration and reload
sudo nginx -t
sudo systemctl reload nginx

SSL Certificate with Let's Encrypt

Let's Encrypt provides free SSL/TLS certificates. The Certbot tool automatically updates the Nginx configuration.

terminal - certbot installation and SSL
# Install Certbot
sudo apt install certbot python3-certbot-nginx -y

# Get SSL certificate for all domains
sudo certbot --nginx -d app1.example.com -d blog.example.com

# Test automatic renewal
sudo certbot renew --dry-run

# Certbot automatic renewal cron is already set up:
# /etc/cron.d/certbot or systemd timer

💡 Tip: Certbot automatically updates Nginx server blocks to redirect to HTTPS. When you add a new domain, first create the HTTP server block, then run certbot --nginx -d new-domain.com.

Upstream and Load Balancing

If multiple instances of the same application are running, you can perform basic load balancing with the Nginx upstream block:

nginx.conf - upstream load balancing
upstream app_backend {
    # Round-robin (default)
    server localhost:3001;
    server localhost:3002;
    server localhost:3003;
}

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

    location / {
        proxy_pass http://app_backend;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

Nginx reverse proxy configuration can be easily applied on Hosted Cloud cloud servers. If you're hosting multiple projects, we also recommend strengthening your server security with our SSH hardening guide. For the official Nginx documentation, you can refer to the proxy module reference.

Frequently Asked Questions

How many domains can I host on a single server?

There's no practical limit from Nginx's perspective; you can define hundreds of server blocks. The limiting factor is your server's CPU, RAM, and bandwidth capacity. Plan capacity by monitoring each application's resource consumption.

Should I use Nginx or Apache?

Nginx is generally more performant for reverse proxy and static file serving. Thanks to its event-driven architecture, Nginx uses less memory and handles more concurrent connections. Apache may be preferred for legacy applications that require .htaccess support.

Do WebSocket connections work through a reverse proxy?

Yes, you just need to add the proxy_set_header Upgrade $http_upgrade and proxy_set_header Connection 'upgrade' headers. These settings are already included in the Node.js example above.

What happens if the backend application crashes?

Nginx returns a 502 Bad Gateway error. To prevent this: (1) Auto-restart the application with PM2 or systemd, (2) Define multiple instances in the upstream block, (3) Route failed requests to another instance with the proxy_next_upstream directive.

Conclusion

Nginx reverse proxy is the standard way to efficiently manage multiple domains and applications on a single server. Create a separate server block for each domain, automate SSL certificates with Let's Encrypt, and perform load balancing with the upstream block when needed. Don't forget to test with nginx -t before making configuration changes.

Manage All Your Projects on a Single Server

Set up Nginx reverse proxy on Hosted Cloud cloud servers and manage all your domains from a single point. Don't compromise on performance with NVMe SSD and high bandwidth.

View Cloud Server Plans →
A

Ahmet Yılmaz

Senior Infrastructure Engineer

With over 10 years of experience in cloud infrastructure and DevOps, Ahmet specializes in Kubernetes, Terraform, and high-availability architectures.

Comments coming soon