Configure Apache Virtual Hosts & Multiple SSL on Ubuntu

Host multiple websites with secure HTTPS on a single server using Apache Virtual Hosts and Certbot.

Estimated Time: Approximately 60 - 90 minutes (for two domains)

Overview: What are Apache Virtual Hosts?

Apache Virtual Hosts allow you to host multiple websites or domains on a single server with a single Apache installation. This is incredibly efficient, as you don't need a separate server for each website you want to run.

Apache determines which website to serve based on the domain name requested by the user's browser. This is called "name-based virtual hosting." Each virtual host configuration specifies the domain, its document root (where its files are stored), logging, and other specific settings.

Why Use Virtual Hosts?

  • Resource Efficiency: Consolidate multiple websites on one server, saving hardware and operational costs.
  • Multi-Domain Hosting: Host `yourdomain1.com`, `yourdomain2.org`, and `sub.yourdomain1.com` all from the same Apache instance.
  • Clean Separation: Each website has its own `DocumentRoot`, logs, and configurations, keeping projects organized.
  • SSL for Each Site: Easily apply unique SSL certificates to each domain for secure HTTPS communication.

This guide will cover setting up two example domains, `yourdomain1.com` and `yourdomain2.com`, configuring them as Apache Virtual Hosts, and then securing both with free SSL certificates from Let's Encrypt using Certbot.

Estimated Time

60 - 90 minutes

(For configuring two domains and setting up SSL. More domains will take slightly longer.)

Experience Level

Intermediate

Assumes basic familiarity with Apache, DNS, and Linux terminal commands (e.g., from our LAMP guide and Certbot guide).

System Requirements & Prerequisites

  • Server: An Ubuntu 22.04 LTS or 20.04 LTS server. You need SSH access to this server.
  • Apache Installed: Apache2 web server must be installed and running. (See our LAMP guide).
  • UFW Configured: UFW must be enabled and configured to allow HTTP (port 80) and HTTPS (port 443) traffic. (See our LAMP guide for `Apache Full` rule).
  • Certbot Installed: Certbot with the Apache plugin should be installed if you intend to secure your sites with SSL. (See our Certbot guide).
  • Registered Domain Names: At least two registered domain names (e.g., `yourdomain1.com` and `yourdomain2.com`).
  • DNS A Records: The DNS `A` records for `yourdomain1.com`, `www.yourdomain1.com`, `yourdomain2.com`, and `www.yourdomain2.com` must be pointed to your Ubuntu server's public IP address. **This is critical and must be done *before* starting this guide.**
  • Sudo Privileges: Access to a terminal as a non-root user with sudo privileges on your Ubuntu server.

Step-by-Step Instructions

Step 1: Update System Packages

Always start by ensuring your system is up-to-date.

sudo apt update && sudo apt upgrade -y

Step 2: Verify Apache and UFW Status

Confirm that Apache is running and your firewall is correctly configured to allow web traffic.

Check Apache status:

sudo systemctl status apache2

Check UFW status:

sudo ufw status verbose

Step 3: Create Directory Structure for New Websites

Each website needs its own dedicated `DocumentRoot`. We'll create separate directories for `yourdomain1.com` and `yourdomain2.com`.

1. Create document root directories:

sudo mkdir -p /var/www/yourdomain1.com/public_html
sudo mkdir -p /var/www/yourdomain2.com/public_html

2. Set ownership and permissions:

sudo chown -R $USER:$USER /var/www/yourdomain1.com
sudo chown -R $USER:$USER /var/www/yourdomain2.com
sudo chmod -R 755 /var/www/yourdomain1.com
sudo chmod -R 755 /var/www/yourdomain2.com

3. Create simple `index.html` files for testing:

echo "<h1>Welcome to yourdomain1.com!</h1>" | sudo tee /var/www/yourdomain1.com/public_html/index.html
echo "<h1>Welcome to yourdomain2.com!</h1>" | sudo tee /var/www/yourdomain2.com/public_html/index.html

Step 4: Create Apache Virtual Host Files (for HTTP)

Apache stores virtual host configurations in `/etc/apache2/sites-available/`. Only files symlinked to `/etc/apache2/sites-enabled/` are active.

1. Create configuration file for `yourdomain1.com`:

sudo nano /etc/apache2/sites-available/yourdomain1.com.conf

Paste the following, replacing `yourdomain1.com` and `www.yourdomain1.com` with your actual domain:

<VirtualHost *:80>
    ServerAdmin webmaster@yourdomain1.com
    ServerName yourdomain1.com
    ServerAlias www.yourdomain1.com
    DocumentRoot /var/www/yourdomain1.com/public_html

    ErrorLog ${APACHE_LOG_DIR}/yourdomain1.com_error.log
    CustomLog ${APACHE_LOG_DIR}/yourdomain1.com_access.log combined

    <Directory /var/www/yourdomain1.com/public_html>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

Save (`Ctrl+O`, `Enter`) and exit (`Ctrl+X`).

2. Create configuration file for `yourdomain2.com`:

sudo nano /etc/apache2/sites-available/yourdomain2.com.conf

Paste the following, replacing `yourdomain2.com` and `www.yourdomain2.com` with your actual domain:

<VirtualHost *:80>
    ServerAdmin webmaster@yourdomain2.com
    ServerName yourdomain2.com
    ServerAlias www.yourdomain2.com
    DocumentRoot /var/www/yourdomain2.com/public_html

    ErrorLog ${APACHE_LOG_DIR}/yourdomain2.com_error.log
    CustomLog ${APACHE_LOG_DIR}/yourdomain2.com_access.log combined

    <Directory /var/www/yourdomain2.com/public_html>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

Save (`Ctrl+O`, `Enter`) and exit (`Ctrl+X`).

Step 5: Enable Virtual Hosts and Restart Apache

Use `a2ensite` to enable your new virtual hosts and `a2dissite` to disable the default Apache configuration, if it conflicts.

1. Enable your new sites:

sudo a2ensite yourdomain1.com.conf
sudo a2ensite yourdomain2.com.conf

2. Disable the default site (if applicable):

sudo a2dissite 000-default.conf

3. Test Apache configuration for syntax errors:

sudo apache2ctl configtest

4. Restart Apache to apply changes:

sudo systemctl restart apache2

Step 6: Verify HTTP Access for Both Domains

Open your web browser and navigate to both domain names. This step is crucial to ensure Apache is serving the correct content before we add SSL.

  • Visit `http://yourdomain1.com` (and `http://www.yourdomain1.com`). You should see "Welcome to yourdomain1.com!"
  • Visit `http://yourdomain2.com` (and `http://www.yourdomain2.com`). You should see "Welcome to yourdomain2.com!"

Step 7: Ensure Certbot is Installed and Ready

If you haven't already, install Certbot with the Apache plugin. This tool will automate the SSL certificate acquisition and Apache configuration.

1. Install Certbot (if needed):

sudo snap install core
sudo snap refresh core
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

2. Enable Apache SSL module (if not already):

sudo a2enmod ssl
sudo systemctl restart apache2

Step 8: Obtain SSL Certificates for Multiple Domains using Certbot

Certbot's Apache plugin is smart enough to detect your virtual hosts and offer to secure them. It will automatically create new SSL-enabled configuration files and set up HTTP to HTTPS redirection.

sudo certbot --apache

Certbot will guide you through a series of prompts:

  1. Email Address: Enter an email for urgent renewal notices and security warnings.
  2. Agree to Terms of Service: Read and accept the Let's Encrypt Subscriber Agreement.
  3. Share Email: Choose whether to share your email with EFF (optional).
  4. Domain Selection: Certbot will list all domains it found in your Apache configuration (e.g., `yourdomain1.com`, `www.yourdomain1.com`, `yourdomain2.com`, `www.yourdomain2.com`).
    Enter the numbers corresponding to ALL domains you want to secure, separated by spaces. For example, if it lists them as `1 2 3 4`, type `1 2 3 4` and press Enter.
  5. HTTPS Redirect: This is important.
    • `1: No Redirect` (Serve both HTTP and HTTPS, not recommended).
    • `2: Redirect` (Recommended) - All HTTP traffic will be automatically redirected to HTTPS.
    Choose option `2` for a secure website.

Step 9: Verify HTTPS Access for Both Domains

After Certbot completes, it's time to verify that both your sites are now serving over HTTPS.

1. Browser Check: Open your web browser and navigate to `https://yourdomain1.com` (and `https://www.yourdomain1.com`). Do the same for `https://yourdomain2.com`.

2. Online SSL Checker (Optional): Use an online tool like SSL Labs SSL Server Test. Enter each of your domain names to get a detailed report on your SSL configuration and grade (aim for A or A+).

Step 10: Verify Certbot Auto-Renewal

Let's Encrypt certificates are valid for 90 days. Certbot automatically sets up a systemd timer or cron job to renew them well before expiration, so you typically don't need to do anything manually.

1. Check the renewal timer status:

sudo systemctl status snap.certbot.renew.service

2. Test the renewal process (dry run): This command simulates a renewal without actually changing your certificates.

sudo certbot renew --dry-run

Final Verification Checklist

Ensure both your websites are fully operational and secured:

  • DNS Points Correctly: Both `yourdomain1.com` and `yourdomain2.com` (and their `www` subdomains) point to your server's public IP.
  • HTTP Accessible (Initially): Before SSL, both sites loaded their respective `index.html` via HTTP.
  • HTTPS Active: Both `https://yourdomain1.com` and `https://yourdomain2.com` display a valid padlock icon in the browser.
  • HTTP Redirects to HTTPS: Accessing `http://` for either domain automatically redirects to `https://`.
  • Certbot Auto-Renewal Confirmed: `sudo certbot renew --dry-run` completes successfully for all secured domains.
  • UFW & Security Group: Ports 80 and 443 are correctly open in your server's firewall.

Conclusion & Next Steps

Congratulations! You have successfully configured Apache Virtual Hosts to serve multiple websites from a single Ubuntu server and secured each domain with free, automatically renewing SSL certificates from Let's Encrypt using Certbot. This is a powerful and essential setup for modern web hosting.

Consider these advanced steps and best practices to further enhance your multi-site server:

  • HSTS (HTTP Strict Transport Security): For an extra layer of security, configure HSTS to ensure browsers *always* connect via HTTPS after the first visit. Certbot usually adds this, but verify.
  • DocumentRoot Permissions: For PHP applications, ensure the `DocumentRoot` directories (e.g., `/var/www/yourdomain1.com/public_html`) have the correct ownership (`www-data:www-data`) and permissions (`755` for directories, `644` for files) for Apache and PHP to operate securely.
  • Database Separation: For multiple PHP applications, create separate MySQL databases and dedicated, restricted MySQL users for each application (as discussed in our Secure Remote MySQL Access guide).
  • Specific User for Website Files: For enhanced security, consider creating a dedicated Linux user for each website's files, granting the `www-data` group read/write access to specific upload directories.
  • Resource Monitoring: Continuously monitor your server's CPU, RAM, and disk I/O. As you add more sites or traffic increases, you may need to scale up your EC2 instance (e.g., to a larger `t3.medium` or `m5.large`).
  • Wildcard Certificates: If you're hosting many subdomains (e.g., `blog.yourdomain.com`, `shop.yourdomain.com`), a wildcard certificate (`*.yourdomain.com`) can simplify management. This requires Certbot's DNS challenge.
  • Load Balancing & Scaling: For high-traffic or critical sites, consider distributing traffic across multiple EC2 instances using an Elastic Load Balancer and Auto Scaling Groups.

Need Expert Web Hosting Solutions or Multi-Site Management? Contact Us!