← Back

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:

GoDaddy DNS Management

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.

  1. Navigate to /etc/nginx/sites-available/.

  2. Remove the default configuration:

    1rm -rf /etc/nginx/sites-available/default 2rm -rf /etc/nginx/sites-enabled/default
  3. Create a new file named sample.conf with the following content:

    /etc/nginx/sites-available/sample.conf
    1server { 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 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:

/etc/nginx/sites-available/sample.conf
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.