When setting up Nginx as a reverse proxy for multiple websites on a single server, the fundamental architecture requires proper server blocks configuration and SSL handling. Your existing configuration shows good practices with HTTP to HTTPS redirection, but needs expansion for multi-domain support.
The key is creating separate server blocks for each domain while maintaining a clean configuration structure. Here's how to extend your existing setup:
# Default HTTP to HTTPS redirect (catch-all for all domains)
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _; # Matches all domains
return 301 https://$host$request_uri;
}
# Domain-specific configurations
server {
listen 443 ssl;
server_name my_domain123.com www.my_domain123.com;
# SSL configuration
ssl_certificate /etc/letsencrypt/live/my_domain123.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/my_domain123.com/privkey.pem;
location / {
proxy_pass http://localhost:4000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
server {
listen 443 ssl;
server_name another_domain.com www.another_domain.com;
# SSL configuration
ssl_certificate /etc/letsencrypt/live/another_domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/another_domain.com/privkey.pem;
location / {
proxy_pass http://localhost:5000; # Different backend port
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
For maintainability, consider these approaches:
- Separate files in sites-available:
# /etc/nginx/sites-available/my_domain123.com server { # Domain-specific config } # /etc/nginx/sites-available/another_domain.com server { # Another domain config }
- Wildcard SSL certificates when appropriate:
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
For more complex setups, you might need:
# Load balancing across multiple backend servers
upstream backend_servers {
server 127.0.0.1:4000;
server 127.0.0.1:4001;
}
server {
listen 443 ssl;
server_name my_domain123.com;
location / {
proxy_pass http://backend_servers;
proxy_next_upstream error timeout invalid_header;
}
}
- SSL Certificate Errors: Ensure each domain has valid certificates
- Port Conflicts: Verify backend applications listen on different ports
- Cache Issues: Consider adding cache-control headers in proxy responses
Let's start by examining the existing nginx configuration that handles a single domain:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name my_domain123.com www.my_domain123.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name localhost www.my_domain123.com;
return 301 https://my_domain123.com$request_uri;
}
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
server_name my_domain123.com;
location / {
proxy_redirect http://localhost:4000 https://my_domain123.com;
# Additional proxy settings...
}
}
To host multiple websites, we need to create separate server blocks for each domain while maintaining the redirect and SSL functionality. Here's how to expand the configuration:
# HTTP to HTTPS redirect for all domains
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name my_domain123.com www.my_domain123.com
domain2.com www.domain2.com
domain3.net www.domain3.net;
return 301 https://$host$request_uri;
}
# HTTPS configuration for primary domain
server {
listen 443 ssl;
server_name my_domain123.com;
ssl_certificate /path/to/domain123.crt;
ssl_certificate_key /path/to/domain123.key;
location / {
proxy_pass http://localhost:4000;
include proxy_params;
}
}
# HTTPS configuration for second domain
server {
listen 443 ssl;
server_name domain2.com www.domain2.com;
ssl_certificate /path/to/domain2.crt;
ssl_certificate_key /path/to/domain2.key;
location / {
proxy_pass http://localhost:5000;
include proxy_params;
}
}
# HTTPS configuration for third domain
server {
listen 443 ssl;
server_name domain3.net www.domain3.net;
ssl_certificate /path/to/domain3.crt;
ssl_certificate_key /path/to/domain3.key;
location / {
proxy_pass http://localhost:6000;
include proxy_params;
}
}
For better maintainability with multiple domains, consider these approaches:
# Method 1: Separate files in sites-available
# /etc/nginx/sites-available/domain123.com
# /etc/nginx/sites-available/domain2.com
# Then symlink to sites-enabled
# Method 2: Wildcard SSL certificate
server {
listen 443 ssl;
server_name *.mydomains.com;
ssl_certificate /path/to/wildcard.crt;
ssl_certificate_key /path/to/wildcard.key;
location / {
proxy_pass http://localhost:$port;
include proxy_params;
}
}
Watch out for these issues when configuring multiple domains:
# 1. Default server conflict
# Always specify one default_server for HTTPS
server {
listen 443 ssl default_server;
server_name _;
return 444; # Close connection
}
# 2. Missing server_name in redirects
# Use $host instead of $server_name for multi-domain setups
return 301 https://$host$request_uri;
# 3. SSL certificate mismatch
# Ensure each domain has its own certificate or a wildcard cert
For more complex setups with load balancing and caching:
upstream backend_domain1 {
server localhost:4000;
server backend1.example.com:4000;
}
upstream backend_domain2 {
server localhost:5000;
server backend2.example.com:5000;
}
server {
listen 443 ssl;
server_name domain1.com;
ssl_certificate /path/to/domain1.crt;
ssl_certificate_key /path/to/domain1.key;
location / {
proxy_pass http://backend_domain1;
proxy_cache my_cache;
proxy_cache_valid 200 1d;
}
}