How to Set Default Variables in Nginx Using the set Directive


2 views

In Nginx configuration, the set directive creates new variables, but doesn't natively provide a "default if undefined" syntax like some programming languages. However, we can implement this functionality through creative use of Nginx's configuration rules.

We can leverage Nginx's evaluation order to create default values:

# First try to use existing value
set $foo $foo;

# Then override if empty/undefined
if ($foo = '') {
    set $foo 'default_value';
}

1. Using map Directive

The map directive provides a cleaner way to handle defaults:

map $foo $foo_with_default {
    ''      'default_value';
    default $foo;
}

server {
    # Now use $foo_with_default throughout your configuration
}

2. Lua Module (for OpenResty/Nginx++)

If you have Lua support, you can set defaults more elegantly:

set_by_lua $foo 'return ngx.var.foo or "default_value"';

Here are practical examples where default values are useful:

# Default cache time
map $arg_cache $cache_time {
    ''      3600;
    default $arg_cache;
}

# Default language setting
map $http_accept_language $site_lang {
    ~*^en 'en';
    ~*^fr 'fr';
    default 'en';
}
  • Variable scoping: Variables set at server level won't be available in location blocks unless redeclared
  • Performance impact: Excessive conditional checks may affect performance
  • Readability: Complex default logic should be documented

When debugging default values, remember:

# Log variable values for debugging
log_format vars '$remote_addr - $remote_user [$time_local] '
               '"$request" $status $body_bytes_sent '
               '"$http_referer" "$http_user_agent" '
               'foo=$foo foo_default=$foo_with_default';

access_log /var/log/nginx/vars.log vars;

When working with Nginx configuration, you'll often need to handle cases where variables might be undefined. Unlike some programming languages that offer built-in default value mechanisms, Nginx's set directive doesn't provide a direct way to specify fallback values.

Here are two effective approaches to implement default variable behavior in Nginx:

# Method 1: Using map directive for conditional defaults
map $foo $foo_default {
    default   "fallback_value";
    ""        "fallback_value";
    ~*        $foo;
}

# Method 2: Nested if blocks in location/server context
set $foo "default_value";
if ($arg_foo) {
    set $foo $arg_foo;
}

Consider a scenario where you need to set a default cache time:

http {
    map $request_uri $cache_time {
        default 3600;
        ~*\.(jpg|png|gif)$ 86400;
        ~*\.(css|js)$ 7200;
    }

    server {
        location / {
            expires $cache_time;
        }
    }
}

For more complex scenarios, you can chain multiple conditions:

set $feature_flag 0;
if ($http_x_feature_flag) {
    set $feature_flag $http_x_feature_flag;
}
if ($arg_debug) {
    set $feature_flag 1;
}

Remember these key points when working with Nginx variables:

  • Variable scope matters (server/location level)
  • Performance impact of complex conditionals
  • The order of directives affects evaluation
  • Debugging can be challenging - use error_log