Configuring Nginx Reverse Proxy to Enable Gzip Compression for Legacy IIS Backend


2 views

Many developers face a common performance challenge when working with older web servers like IIS 6.0 that lack reliable gzip compression. Here's how we can leverage Nginx's powerful reverse proxy capabilities to solve this issue.

The current configuration shows Nginx serving as a reverse proxy for an IIS 6.0 backend. While the proxy setup works, the missing piece is effective gzip compression between Nginx and end users.

For optimal performance, we need Nginx to:

  • Proxy requests to IIS backend
  • Compress responses when appropriate
  • Handle various content types
  • Maintain proper headers
# Main gzip configuration
gzip on;
gzip_min_length 1000;
gzip_buffers 16 8k;
gzip_comp_level 6;
gzip_http_version 1.1;
gzip_proxied any;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
gzip_vary on;

# Proxy configuration
server {
    listen 80;
    server_name www.mydomain.co.uk;
    
    location / {
        proxy_pass http://192.168.5.37;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        
        # Important for proper gzip handling
        proxy_http_version 1.1;
        proxy_set_header Accept-Encoding "";
    }
}

The key elements that make this work:

  • proxy_http_version 1.1: Ensures proper HTTP protocol version for compression
  • proxy_set_header Accept-Encoding "": Prevents compressed responses from backend
  • gzip_proxied any: Allows compression for all proxied responses

To confirm the setup works:

curl -I -H "Accept-Encoding: gzip" http://localhost/css/style.css

Look for these headers in response:

Content-Encoding: gzip
Vary: Accept-Encoding

When implementing this solution:

  • Adjust gzip_comp_level (1-9) based on CPU resources
  • Monitor memory usage with gzip_buffers
  • Consider adding more MIME types to gzip_types
  • Test with different gzip_min_length values

When dealing with legacy infrastructure like IIS 6.0, we often encounter situations where modern performance optimizations like Gzip compression don't work reliably. This becomes particularly problematic when serving static assets like CSS and JavaScript files to modern browsers that support compression.

The solution is to implement Nginx as a reverse proxy that handles compression independently of the backend server. Here's why this approach works:

  • Nginx has excellent Gzip implementation that's more reliable than IIS 6.0
  • We can maintain security updates on Nginx while keeping the legacy backend
  • The compression happens closer to the client, reducing bandwidth usage

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

# Main Gzip Configuration
gzip on;
gzip_min_length 1000;
gzip_buffers 4 8k;
gzip_http_version 1.1;
gzip_comp_level 6;
gzip_types text/plain text/css application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;
gzip_vary on;
gzip_proxied any;

# Proxy Configuration
server {
    listen 80;
    server_name www.mydomain.co.uk;

    location / {
        proxy_pass http://192.168.5.37;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        
        # Important for proper compression handling
        proxy_set_header Accept-Encoding "";
        proxy_ignore_headers Vary;
    }
}

The critical parts that make this work:

  • gzip_proxied any - Enables compression for proxied responses
  • proxy_set_header Accept-Encoding "" - Prevents compression conflicts
  • proxy_ignore_headers Vary - Ensures consistent caching behavior

After implementing these changes, verify the compression with:

curl -I -H "Accept-Encoding: gzip" http://www.mydomain.co.uk/css/components.css

You should see headers indicating compression:

Content-Encoding: gzip
Vary: Accept-Encoding

For best results:

  • Adjust gzip_comp_level between 1 (fastest) and 9 (best compression)
  • Consider adding more file types to gzip_types like fonts and SVGs
  • Monitor memory usage with gzip_buffers on high-traffic servers

If you need more control:

# Selective compression by file extension
location ~* \.(css|js|html)$ {
    gzip_static on;
    gzip_proxied expired no-cache no-store private auth;
}