How to Configure Nginx to Listen on Multiple Ports with Different Content


4 views

Yes, Nginx can absolutely listen on multiple ports simultaneously, and you can serve different content for each port. The confusion about port collisions typically occurs when multiple services try to bind to the same port or when firewall rules aren't properly configured.

Here's a fundamental example of an Nginx configuration that listens on two different ports (8080 and 8081) with different content:


server {
    listen 8080;
    server_name localhost;

    location / {
        root /var/www/port8080;
        index index.html;
    }
}

server {
    listen 8081;
    server_name localhost;

    location / {
        root /var/www/port8081;
        index index.html;
    }
}

The key to preventing collisions is ensuring:

  • Each port number is unique in your configuration
  • No other service is using those ports
  • Azure NSG rules allow traffic on those ports

For more sophisticated scenarios where you want to serve completely different applications based on port:


server {
    listen 9090;
    server_name localhost;

    location / {
        proxy_pass http://localhost:3000; # Node.js app
        proxy_set_header Host $host;
    }
}

server {
    listen 9091;
    server_name localhost;

    location / {
        proxy_pass http://localhost:8000; # Python app
        proxy_set_header Host $host;
    }
}

After making changes:

  1. Test configuration: sudo nginx -t
  2. Reload Nginx: sudo systemctl reload nginx
  3. Check listening ports: sudo netstat -tulnp | grep nginx

On Azure VMs, remember to:

  • Add inbound security rules for each port in NSG
  • Check Azure Load Balancer rules if applicable
  • Consider using Application Gateway for more complex routing

If ports aren't working:


# Check if port is open
telnet your-vm-ip 8080

# Check firewall
sudo ufw status

# Check SELinux (if enabled)
sudo ausearch -m avc -ts recent

Nginx can indeed listen to multiple ports simultaneously and serve different content for each port. This is achieved through server blocks (similar to Apache's virtual hosts) where each block defines a separate configuration for a specific port.

Here's a simple configuration that makes Nginx listen on ports 8080 and 8081 with different content:


server {
    listen 8080;
    server_name localhost;

    location / {
        root /var/www/port8080;
        index index.html;
    }
}

server {
    listen 8081;
    server_name localhost;

    location / {
        root /var/www/port8081;
        index index.html;
    }
}

The "collision" you mentioned typically occurs when:

  • Another service is already using the port
  • SELinux or firewall restrictions exist
  • Nginx doesn't have permission to bind to the port

For HTTPS on multiple ports, you can extend the configuration:


server {
    listen 8443 ssl;
    server_name example.com;

    ssl_certificate /etc/ssl/certs/example.com.crt;
    ssl_certificate_key /etc/ssl/private/example.com.key;

    location / {
        root /var/www/secure-app;
        index index.html;
    }
}

After configuration:

  1. Test configuration: nginx -t
  2. Reload Nginx: systemctl reload nginx
  3. Check port availability: netstat -tulnp | grep nginx

On Azure VMs, remember to:

  • Open ports in Azure Network Security Group
  • Configure the VM's local firewall (iptables/ufw)
  • Verify the VM's public IP allows the ports