Comprehensive Guide: Hosting Multiple Domains with Nginx and Let's Encrypt
As developers, we often prefer hosting multiple services on a single instance during prototyping to streamline the process and reduce overhead. This guide demonstrates how to host multiple domains efficiently on one server using Nginx and Let's Encrypt in an Linux environment. You'll learn to set up a secure, scalable environment that accommodates multiple services, optimizing your workflow and resource utilization while leveraging the power and flexibility of Linux-based systems.
Prepare a New Server
For this guide, I'm using a DigitalOcean droplet with Ubuntu 24.04.
Configure the DNS
Configure your DNS by creating two A records that point to your server:
- directus.domain.com ->
<server_ip>
- meilisearch.domain.com ->
<server_ip>
GoDaddy DNS Management
After configuration, allow time for DNS propagation.
Assumed Services Configuration
Let's assume we have two services running on the instance with different ports:
- directus → 192.168.1.1:8055
- meilisearch → 192.168.1.1:7700
Install NGINX
Install NGINX using the following command:
1sudo apt-get install nginx -y
Set Up NGINX Configuration
This NGINX server configuration sets up reverse proxies for both Directus and MeiliSearch and forwards the HTTP requests to their respective local ports.
-
Navigate to
/etc/nginx/sites-available/
. -
Remove the default configuration:
1rm -rf /etc/nginx/sites-available/default 2rm -rf /etc/nginx/sites-enabled/default
-
Create a new file named
sample.conf
with the following content:/etc/nginx/sites-available/sample.conf1server { 2 listen 80; 3 server_name directus.domain.com; 4 5 location / { 6 proxy_pass <http://localhost:8055>; 7 proxy_http_version 1.1; 8 proxy_set_header Upgrade $http_upgrade; 9 proxy_set_header Connection 'upgrade'; 10 proxy_set_header Host $host; 11 proxy_cache_bypass $http_upgrade; 12 } 13} 14 15server { 16 listen 80; 17 server_name meilisearch.domain.com; 18 19 location / { 20 proxy_pass <http://localhost:7700>; 21 proxy_http_version 1.1; 22 proxy_set_header Upgrade $http_upgrade; 23 proxy_set_header Connection 'upgrade'; 24 proxy_set_header Host $host; 25 proxy_cache_bypass $http_upgrade; 26 } 27}
Validate the Configuration
Run this command to validate the NGINX configuration:
1nginx -t
You should see:
1nginx: the configuration file /etc/nginx/nginx.conf syntax is ok 2nginx: configuration file /etc/nginx/nginx.conf test is successful
Create a Symbolic Link
Create a symbolic link to enable the configuration:
1ln -s /etc/nginx/sites-available/sample.conf /etc/nginx/sites-enabled/
Restart NGINX
Restart the NGINX service:
1sudo service nginx restart
Access Services via Browser
Try accessing your services using the domain names you set up earlier. The websites should load, but you may see a "Not Secure" warning in your browser.
Install Let's Encrypt with Certbot
To resolve the security warning and enable SSL/TLS encryption, we'll use Let's Encrypt to install free certificates with automatic renewal:
1sudo apt-get install certbot python3-certbot-nginx -y
Note: Certbot is a tool developed by the Electronic Frontier Foundation (EFF) to automate the process of obtaining and renewing SSL certificates from Let's Encrypt, a free Certificate Authority (CA).
Dry Run Certbot
Let's Encrypt has rate limits, so it's best to perform a dry run first:
1sudo certbot certonly --nginx \ 2 --domains directus.domain.com \ 3 --domains meilisearch.domain.com \ 4 --dry-run \ 5 --non-interactive \ 6 --agree-tos \ 7 --email <email_address>
Replace <email_address>
with your actual email.
If successful, you'll see:
1Saving debug log to /var/log/letsencrypt/letsencrypt.log 2Simulating a certificate request for directus.domain.com and meilisearch.domain.com 3The dry run was successful.
Request Actual SSL Certificates
Remove the --dry-run
flag to obtain actual certificates:
1sudo certbot certonly --nginx \ 2 --domains directus.domain.com \ 3 --domains meilisearch.domain.com \ 4 --non-interactive \ 5 --agree-tos \ 6 --email <email_address>
This uses the certbot --nginx
command and NGINX plugin to perform certificate generation and installation via the HTTP-01 challenge and DNS validation.
Reconfigure NGINX
This configures two NGINX server blocks using the server_name
directive to enable SSL termination and forward HTTPS traffic to the backend services. The SSL configuration follows best practices for strong SSL security and should score well on the SSL Labs Server Test.
This redirection is a best practice for maintaining a secure and professional web presence.
Update /etc/nginx/sites-available/sample.conf
to use SSL:
1server { 2 listen 80; 3 server_name directus.domain.com; 4 return 301 https://$server_name$request_uri; 5} 6 7server { 8 listen 443 ssl; 9 server_name directus.domain.com; 10 11 ssl_certificate /etc/letsencrypt/live/directus.domain.com/fullchain.pem; 12 ssl_certificate_key /etc/letsencrypt/live/directus.domain.com/privkey.pem; 13 14 ssl_protocols TLSv1.2 TLSv1.3; 15 ssl_prefer_server_ciphers on; 16 ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; 17 18 location / { 19 proxy_pass <http://localhost:8055>; 20 proxy_http_version 1.1; 21 proxy_set_header Upgrade $http_upgrade; 22 proxy_set_header Connection 'upgrade'; 23 proxy_set_header Host $host; 24 proxy_cache_bypass $http_upgrade; 25 proxy_set_header X-Real-IP $remote_addr; 26 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 27 proxy_set_header X-Forwarded-Proto $scheme; 28 } 29} 30 31server { 32 listen 443 ssl; 33 server_name meilisearch.domain.com; 34 35 ssl_certificate /etc/letsencrypt/live/directus.domain.com/fullchain.pem; 36 ssl_certificate_key /etc/letsencrypt/live/directus.domain.com/privkey.pem; 37 38 ssl_protocols TLSv1.2 TLSv1.3; 39 ssl_prefer_server_ciphers on; 40 ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; 41 42 location / { 43 proxy_pass <http://localhost:7700>; 44 proxy_http_version 1.1; 45 proxy_set_header Upgrade $http_upgrade; 46 proxy_set_header Connection 'upgrade'; 47 proxy_set_header Host $host; 48 proxy_cache_bypass $http_upgrade; 49 proxy_set_header X-Real-IP $remote_addr; 50 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 51 proxy_set_header X-Forwarded-Proto $scheme; 52 } 53}
Validate and Restart NGINX
Validate the new configuration and restart NGINX:
1nginx -t 2sudo service nginx restart
Access Services via HTTPS
Your services should now be accessible via HTTPS without any security warnings.
Set Up Automatic Certificate Renewal
Let's Encrypt certificates are valid for 90 days. To avoid certificate expiration, setup a cronjob to automatically renew certificates:
1sudo crontab -e
Add this line to run renewal checks daily:
10 0 * * * /usr/bin/certbot renew --quiet
This uses the certbot auto renew feature to keep certificates up-to-date.
Conclusion
In this comprehensive guide, we've explored the process of hosting multiple domains using Nginx and securing them with Let's Encrypt SSL certificates. We've covered essential steps from DNS configuration to automatic certificate renewal, providing a robust foundation for hosting multiple services on a single server.
Key takeaways from this tutorial include:
- Efficient DNS configuration for multiple domains
- Proper Nginx setup for reverse proxying multiple services
- Securing your domains with free SSL certificates from Let's Encrypt
- Implementing best practices for SSL configuration
- Setting up automatic certificate renewal to ensure continuous security
By mastering these techniques, developers can create a scalable and secure hosting environment for multiple services. This approach not only enhances security but also improves SEO, user trust, and overall professionalism of your web presence.
I hope this guide has provided valuable insights into managing multiple domains securely and efficiently.
As you implement these practices, you'll be well-equipped to handle complex hosting scenarios and deliver a superior experience to your users.