When configuring nginx for multiple domains in a single server block, we often face readability issues with long server_name
declarations. The default approach quickly becomes unwieldy:
server {
listen *:80;
server_name example.com example.net example.org example.co example.io example.tech;
return 301 https://canonical-domain.com$request_uri;
}
While nginx doesn't support traditional line continuation with backslashes like shell scripts, we have several practical alternatives:
# Option 1: Multiple server_name directives
server {
listen *:80;
server_name example.com example.net example.org;
server_name example.co example.io example.tech;
return 301 https://canonical-domain.com$request_uri;
}
# Option 2: Using include files
server {
listen *:80;
include /etc/nginx/conf.d/domains.conf;
return 301 https://canonical-domain.com$request_uri;
}
For extremely large domain lists (50+), consider using the map
directive for better maintainability:
map $host $canonical_host {
default "canonical-domain.com";
include /etc/nginx/conf.d/domain-mappings.conf;
}
server {
listen *:80;
server_name _;
if ($canonical_host) {
return 301 https://$canonical_host$request_uri;
}
# Handle non-mapped domains here
}
While all these methods work, be aware that:
- Multiple
server_name
directives have minimal performance impact include
files are parsed at configuration load timemap
directives are evaluated per request
For environments with wildcard domains, combine patterns with specific exceptions:
server {
listen *:80;
server_name "~^(www\.)?example\.(com|net|org)$";
server_name sub.example.io special.example.co;
return 301 https://main-site.com$request_uri;
}
When managing nginx configurations with numerous domains in the server_name
directive, you often encounter messy, hard-to-maintain configurations like this:
server {
listen *:80;
server_name example.com test.com demo.com staging.com production.com
beta.com alpha.com dev.com www.example.com blog.example.com
shop.example.com api.example.com;
rewrite ^(.*) http://canonical.com permanent;
}
Unlike some other configuration formats, nginx doesn't support traditional line continuation characters like backslashes. However, you can simply split the domains across multiple lines naturally:
server {
listen *:80;
server_name
example.com
test.com
demo.com
staging.com
production.com
beta.com
alpha.com
dev.com
www.example.com
blog.example.com
shop.example.com
api.example.com;
rewrite ^(.*) http://canonical.com permanent;
}
For extremely large domain lists, consider these additional methods:
# Method 1: Include external file
server {
listen *:80;
include /etc/nginx/domains.conf;
rewrite ^(.*) http://canonical.com permanent;
}
# domains.conf contents:
server_name
domain1.com
domain2.com
...;
Or using regex patterns if domains follow consistent naming:
server {
listen *:80;
server_name ~^(www\.)?(example|test|demo|staging)\.com$;
rewrite ^(.*) http://canonical.com permanent;
}
The multi-line approach provides several advantages:
- Better version control diffs
- Easier domain management
- Improved readability
- Simpler commenting for individual domains
Here's how you might implement it with comments:
server {
listen *:80;
server_name
# Production domains
example.com
www.example.com
# Development domains
test.com
dev.example.com
# Regional domains
us.example.com
eu.example.com;
rewrite ^(.*) http://canonical.com permanent;
}