When managing multiple domain variations (like example.com, example.co.uk, example.net) that all point to the same website content, many developers create separate server blocks in their NGINX configuration. This approach works but leads to unnecessary code duplication:
server {
listen 80;
server_name example.com www.example.com;
root /var/www/example.com/html;
}
server {
listen 80;
server_name example.co.uk www.example.co.uk;
root /var/www/example.com/html;
}
NGINX allows you to handle all domain variations in a single server block by listing multiple domains in the server_name
directive:
server {
listen 80;
server_name example.com www.example.com
example.co.uk www.example.co.uk
example.net www.example.net;
root /var/www/example.com/html;
}
For more complex scenarios, you can use regular expressions or wildcards:
server {
listen 80;
server_name ~^(www\.)?example\.(com|co\.uk|net)$;
root /var/www/example.com/html;
# Additional settings
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
When using SSL certificates (especially wildcard or multi-domain certificates), this approach becomes even more valuable:
server {
listen 443 ssl;
server_name example.com www.example.com
example.co.uk www.example.co.uk;
ssl_certificate /etc/ssl/certs/wildcard_example.crt;
ssl_certificate_key /etc/ssl/private/wildcard_example.key;
root /var/www/example.com/html;
}
Using a single server block offers several advantages:
- Reduced configuration file size
- Simpler maintenance
- Faster NGINX startup (fewer blocks to parse)
- Consistent behavior across all domains
To verify your configuration works for all domains:
sudo nginx -t # Test configuration
sudo systemctl reload nginx # Apply changes
curl -I http://example.com
curl -I http://example.co.uk
When managing multiple domain variants (like example.com, example.co.uk, example.net) that all point to identical content, creating separate server blocks for each domain violates the DRY (Don't Repeat Yourself) principle. Not only does this create maintenance overhead, but it also makes your nginx configuration unnecessarily verbose.
Nginx's server_name
directive supports multiple domain declarations in a single server block. Here's the optimized configuration:
server {
listen 80;
server_name example.com www.example.com
example.co.uk www.example.co.uk
example.net www.example.net
example.org www.example.org;
root /var/www/example.com/html;
# Additional recommended directives
index index.html index.php;
access_log /var/log/nginx/example.access.log;
error_log /var/log/nginx/example.error.log;
}
For more complex domain patterns, you can use regular expressions:
server {
listen 80;
server_name ~^(www\.)?example\.(com|co\.uk|net|org)$;
root /var/www/example.com/html;
}
If using HTTPS with a wildcard or multi-domain certificate:
server {
listen 443 ssl http2;
server_name example.com www.example.com
example.co.uk www.example.co.uk;
ssl_certificate /etc/ssl/certs/wildcard_example.crt;
ssl_certificate_key /etc/ssl/private/wildcard_example.key;
root /var/www/example.com/html;
}
While this approach is cleaner, be aware that:
- Nginx processes server blocks in order - place your catch-all blocks last
- Extremely long server_name lists may impact performance
- For 100+ domains, consider using a map directive or separate include files
Here's my production configuration for a SaaS platform serving multiple TLDs:
# Primary domains
server {
listen 80;
listen [::]:80;
server_name app.example.com app.example.net
app.example.io app.example.co
app.example.tech app.example.dev;
root /var/www/app/current/public;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# PHP-FPM configuration
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
}
}
# Redirect all HTTP to HTTPS
server {
listen 80;
server_name ~^(www\.)?example\.(com|net|io|co|tech|dev)$;
return 301 https://$host$request_uri;
}
- Missing semicolons at line endings
- Not including www/non-www variants
- Forgetting to reload nginx after changes (
sudo systemctl reload nginx
) - DNS not properly configured for all domains