How to Share Common Nginx Configuration Across Multiple Locations


3 views

When configuring Nginx, we often encounter situations where multiple location blocks need identical proxy settings. Copy-pasting the same configuration leads to maintenance headaches and potential inconsistencies. Here's a typical scenario:

location / {
    proxy_pass        http://127.0.0.1:9000/;
    proxy_redirect    off;
    proxy_set_header  Host             $http_host;
    proxy_set_header  X-Real-IP        $remote_addr;
    proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for;
    # ... more common settings ...
}

location /api {
    # Needs same proxy settings but with additional customizations
}

The cleanest approach is to externalize common configurations into a separate file:

# common_proxy.conf
proxy_pass        http://127.0.0.1:9000/;
proxy_redirect    off;
proxy_set_header  Host             $http_host;
proxy_set_header  X-Real-IP        $remote_addr;
proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for;

Then include it in your location blocks:

location / {
    include common_proxy.conf;
    proxy_cache cache-test;
    proxy_cache_valid 200 302 24h;
}

location /api/0.1/user {
    include common_proxy.conf;
    proxy_cache_key /user/$http_authorization;
}

For more complex scenarios, you can use nested locations:

location / {
    proxy_pass        http://127.0.0.1:9000/;
    proxy_redirect    off;
    proxy_set_header  Host             $http_host;
    proxy_set_header  X-Real-IP        $remote_addr;
    
    location /api/0.1/user {
        proxy_cache_key /user/$http_authorization;
    }
}

Remember these key points when sharing configurations:

  • Always test with nginx -t after changes
  • Order matters - Nginx processes locations in specific order
  • Variables in included files will be evaluated in the context of their parent block
  • For complex setups, consider using the map directive

Here's how we implemented this in our production environment:

# api_gateway.conf
location ~ ^/api/v[0-9]+/(user|product|order) {
    include proxy_common.conf;
    
    # Custom cache settings for API endpoints
    proxy_cache api_cache;
    proxy_cache_valid 200 10m;
    
    if ($request_method = POST) {
        set $no_cache 1;
    }
    
    proxy_no_cache $no_cache;
    proxy_cache_bypass $no_cache;
}

When configuring Nginx as a reverse proxy, we often need to apply the same proxy settings (like headers, caching, and timeouts) across multiple location blocks. The naive approach of copying the configuration leads to maintenance headaches and potential inconsistencies.

location / {
    proxy_pass        http://127.0.0.1:9000/;
    proxy_redirect    off;
    proxy_set_header  Host             $http_host;
    proxy_set_header  X-Real-IP        $remote_addr;
    proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for;
    # ... more common settings ...
}

location /special/route {
    # Needs same proxy settings but with customizations
}

Nginx provides the include directive to share configurations between blocks. Create a separate file for common proxy settings:

# common-proxy.conf
proxy_pass        http://127.0.0.1:9000/;
proxy_redirect    off;
proxy_set_header  Host             $http_host;
proxy_set_header  X-Real-IP        $remote_addr;
proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for;
proxy_cache       cache-test;
proxy_cache_valid 200 302 24h;
proxy_cache_valid 404 60s;
add_header        X-Cache-Status $upstream_cache_status;

Then include it in your location blocks:

location / {
    include common-proxy.conf;
}

location /api/0.1/user {
    include common-proxy.conf;
    proxy_cache_key /user/$http_authorization;
}

For routes under a common prefix, you can use nested locations:

location /api/ {
    include common-proxy.conf;
    
    location /api/0.1/user {
        proxy_cache_key /user/$http_authorization;
    }
    
    location /api/0.1/admin {
        proxy_cache_key /admin/$http_authorization;
    }
}

1. The order of directives matters - Nginx processes them sequentially
2. Variables in included files must be defined in the proper context
3. Always test with nginx -t after configuration changes