While Nginx doesn't support traditional if/else statements at the server block level like some programming languages, there are several effective workarounds to achieve similar conditional behavior in your configuration.
The map directive allows you to create variables whose values depend on other variables:
http {
map $http_user_agent $target_backend {
"~*wget" website1;
default website2;
}
server {
listen 80;
server_name _;
if ($target_backend = website1) {
rewrite ^ http://website1.example$request_uri? permanent;
}
if ($target_backend = website2) {
rewrite ^ http://website2.example$request_uri? permanent;
}
}
}
A more maintainable approach uses separate server blocks:
server {
listen 80;
server_name website1.example www.website1.example;
if ($http_user_agent ~* wget) {
root /website1/;
# Additional configuration for wget clients
}
}
server {
listen 80;
server_name website2.example www.website2.example;
if ($http_user_agent !~* wget) {
root /website2/;
# Configuration for non-wget clients
}
}
For complex conditional logic, consider OpenResty which extends Nginx with Lua:
http {
lua_package_path "/path/to/lua/scripts/?.lua;;";
init_by_lua_block {
-- Initialize any Lua logic here
}
server {
listen 80;
location / {
access_by_lua_block {
if ngx.var.http_user_agent:find("wget") then
ngx.var.root = "/website1/";
else
ngx.var.root = "/website2/";
end
}
}
}
}
- Avoid complex if conditions in the main configuration
- Use map directives for simple conditionals
- Consider splitting configurations into separate files
- Test all conditions thoroughly before deploying
While these methods work, be aware that:
- If conditions are evaluated for every request
- Complex regex patterns can impact performance
- Map directives are evaluated during configuration
While Nginx doesn't support traditional if/else statements at the server block level like programming languages, we can achieve similar functionality using its built-in conditional directives and map modules. The key difference is that Nginx evaluates conditions during configuration parsing rather than at runtime for server blocks.
Here's how to implement user-agent based server selection:
http {
map $http_user_agent $target_server {
default "website2";
"~*wget" "website1";
}
server {
listen 192.0.2.11:1111;
root /website1/;
server_name website1.example www.website1.example;
if ($target_server != "website1") {
return 444; # Close connection if not matching
}
}
server {
listen 192.0.2.22:22222;
root /website2/;
server_name website2.example www.website2.example;
}
}
For more complex scenarios, consider port-based routing:
server {
listen 80;
server_name example.com;
location / {
if ($http_user_agent ~* wget) {
proxy_pass http://192.0.2.11:1111;
}
proxy_pass http://192.0.2.22:22222;
}
}
Remember that extensive conditional checks in Nginx can impact performance. For high-traffic sites, consider:
- Using Lua scripting with OpenResty for complex logic
- Implementing the logic at the application level
- Using separate domain names for different user agents
Always validate your Nginx config changes:
nginx -t
service nginx reload
You can test the user agent detection with curl:
curl -A "wget" http://example.com
curl http://example.com