# Base configuration for HTTP to HTTPS redirect
server {
listen 80;
server_name ~^(?.*)\.?example\.com$;
# Preserve original request URI and protocol
return 301 https://$subdomain.example.com$request_uri;
}
When implementing HTTP to HTTPS redirects in Nginx, developers often face the subdomain preservation issue. The naive approach using simple regex captures the path but loses valuable subdomain information. This becomes critical for:
- Multi-tenant SaaS applications
- Development/staging environments
- Custom domain configurations
Here's the optimized configuration that handles all edge cases:
# Primary redirect configuration
server {
listen 80 default_server;
server_name _;
# Dynamic capture of all possible subdomains
if ($host ~* ^(www\.)?(?.+?)\.(?.+)$) {
set $full_domain $subdomain.$domain;
}
# Special case for naked domain
if ($host ~* ^(?[^/]+)$) {
set $full_domain $domain;
}
return 301 https://$full_domain$request_uri;
}
# HTTPS server block (companion configuration)
server {
listen 443 ssl;
server_name ~^(?.*)\.?example\.com$;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
# Your regular server configuration...
}
For complex deployments, consider these enhancements:
# Handle edge cases with map directive
map $host $redirect_host {
default $host;
"~*^www\.(.*)" $1; # Strip www prefix if present
}
server {
listen 80;
server_name ~^(.*)\.?example\.com$;
# Preserve query parameters
return 301 https://$redirect_host$request_uri;
}
# Special case for HTTP/2 optimization
server {
listen 443 ssl http2;
server_name ~^(?.+)\.example\.com$;
# HSTS header for security
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# ... other SSL configurations
}
Verify your configuration works with these test cases:
- http://example.com → https://example.com
- http://app.example.com → https://app.example.com
- http://dev.app.example.com → https://dev.app.example.com
- http://example.com/path?query=1 → https://example.com/path?query=1
Use this curl command to validate redirects:
curl -I http://sub.example.com/some/path
- Redirect loops: Ensure your SSL server block isn't accidentally listening on port 80
- Wildcard certificates: Verify your SSL cert covers all subdomains
- Performance impact: Use
return 301
instead ofrewrite
for better efficiency
When implementing HTTP-to-HTTPS redirects in Nginx, a common approach is:
server { listen 80; server_name mysite.com; location / { rewrite ^(.*) https://mysite.com$1 permanent; } }
This works fine for the main domain, but has a critical flaw - it strips away subdomain information. Requests to node1.mysite.com
get redirected to https://mysite.com
, losing the node1
subdomain.
The proper way to maintain subdomains is to use Nginx's $host
variable, which contains the original hostname from the request:
server { listen 80; server_name ~^(.*)\.?mysite\.com$; return 301 https://$host$request_uri; }
Key improvements:
$host
preserves the original hostname (including subdomains)$request_uri
preserves the full original URI including query parameters- Using
return 301
is more efficient thanrewrite
for simple redirects - The regex server_name pattern matches all subdomains
For sites with dynamic subdomains, you might want to use a wildcard SSL certificate and handle all possible subdomains:
server { listen 80; server_name ~^(.+)\.mysite\.com$ mysite.com; if ($host ~* ^(.*)\.mysite\.com$) { return 301 https://$host$request_uri; } return 301 https://mysite.com$request_uri; }
For high-traffic sites, consider these optimizations:
server { listen 80 reuseport; server_name ~^(.*)\.?mysite\.com$; # Cache redirects for 1 hour add_header Cache-Control "public, max-age=3600"; return 301 https://$host$request_uri; }
After making changes, always:
- Test with
nginx -t
- Reload with
nginx -s reload
- Verify with curl:
curl -I http://test.mysite.com
The response should show a 301 redirect to the HTTPS version with the subdomain intact.