How to Configure Nginx Reverse Proxy by Domain Name with Dynamic DNS Backend


4 views

I recently faced a situation where I needed to configure an Nginx server to:

  1. Continue serving existing traffic for www.hello.com normally
  2. Intercept requests coming via somedomain.dnsdynamic.com (which points to the same IP)
  3. Proxy all such requests (GET, POST, etc.) to finalserver.example.com
  4. Handle the fact that the backend server has a dynamic IP

Here's the complete Nginx configuration that worked for me:

server {
    listen 80;
    server_name www.hello.com;
    
    # Original configuration for www.hello.com
    root /var/www/hello.com;
    index index.html;
    
    location / {
        try_files $uri $uri/ =404;
    }
}

server {
    listen 80;
    server_name somedomain.dnsdynamic.com;
    
    # Proxy all requests to finalserver.example.com
    location / {
        proxy_pass http://finalserver.example.com;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        
        # Additional proxy settings
        proxy_redirect off;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}
  • The proxy_set_header Host $host preserves the original host header
  • We maintain two separate server blocks to handle different domains
  • Using the hostname (finalserver.example.com) rather than IP handles dynamic DNS
  • All HTTP methods (GET, POST, etc.) are automatically proxied

When I first implemented this, I encountered:

502 Bad Gateway - Usually means Nginx can't resolve finalserver.example.com
404 Not Found - Typically indicates the proxy_pass URL is incorrect

Solutions:

  1. Ensure DNS resolution works (test with ping finalserver.example.com)
  2. Verify the backend server is running and accessible
  3. Check Nginx error logs (/var/log/nginx/error.log)

For production environments, consider adding:

# Proxy timeout settings
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;

# Buffer settings
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;

This configuration has been running stably in production for several months, handling thousands of requests daily with no issues.


We have an existing Nginx server handling requests for www.hello.com. Now, we need to implement a proxy configuration where:

  • All requests coming through somedomain.dnsdynamic.com (pointing to the same IP as www.hello.com)
  • Should be proxied to finalserver.example.com
  • The target server has a dynamic IP, so we must use hostname resolution
  • Original www.hello.com traffic should remain unaffected

Here's the complete Nginx server block configuration that solves this problem:

server {
    listen 80;
    server_name somedomain.dnsdynamic.com;
    
    location / {
        proxy_pass http://finalserver.example.com;
        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;
        
        # Important for WebSocket and long-polling connections
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        
        # Timeout settings
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
    }
}

server {
    listen 80;
    server_name www.hello.com;
    # Your existing configuration for www.hello.com
    # ...
}

1. Server Name Matching: The first server block specifically listens for requests to somedomain.dnsdynamic.com.

2. Proxy Headers: We include essential headers to properly forward:

  • Original host information
  • Client IP address
  • Forwarding protocol

3. Timeout Settings: Configured to prevent premature disconnections.

Since finalserver.example.com has a dynamic IP, Nginx needs to handle DNS resolution properly. Add this to your http block:

http {
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 10s;
    # ... rest of your http configuration
}

This ensures Nginx can resolve the hostname even when the IP changes.

502 Bad Gateway: Typically occurs when:

  • DNS resolution fails - check your resolver configuration
  • Target server is unreachable - verify network connectivity
  • SSL issues if proxying HTTPS - may need proper certificate configuration

404 Not Found: Usually means:

  • The Host header isn't being passed correctly - verify proxy_set_header Host
  • Path rewriting is needed - you might need to adjust the location block

If you need to proxy HTTPS traffic:

server {
    listen 443 ssl;
    server_name somedomain.dnsdynamic.com;
    
    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;
    
    location / {
        proxy_pass https://finalserver.example.com;
        proxy_ssl_server_name on;
        # Include all previous proxy settings
        # ...
    }
}

The proxy_ssl_server_name directive is crucial when proxying HTTPS to a hostname.

After making changes:

  1. Test configuration: nginx -t
  2. Reload Nginx: nginx -s reload
  3. Verify with curl: curl -H "Host: somedomain.dnsdynamic.com" http://your-server-ip/

For HTTPS testing:

curl -k -H "Host: somedomain.dnsdynamic.com" https://your-server-ip/