keepcalculator

06 Numbers and Powers

Apache Virtual Hosts: Host Multiple Sites on One Server

Card No. 06·63407 · Updated · Standard formula, shown below

Apache virtual hosts let you host multiple websites on a single server by mapping different domain names or IP addresses to different document roots. You configure this by adding <VirtualHost> blocks in Apache’s configuration files, each defining which domain requests go to which folder on your server. This guide explains how virtual hosts work, how to set them up, and common pitfalls to avoid.

What Are Virtual Hosts?

Virtual hosting is Apache’s method of running more than one website on one machine. Instead of installing a separate web server for each site, you use one Apache instance that inspects the incoming request and decides which website to serve based on the domain name (or IP address) the client asked for. This is how shared hosting providers pack hundreds of sites onto a single server.

There are two main types:

  • Name-based virtual hosts – the server uses the Host header sent by the browser to pick the correct site. This is the most common method and requires no extra IP addresses.
  • IP-based virtual hosts – each site has its own IP address, and Apache chooses the site based on the IP the request was sent to. This is rarely needed today because name-based hosting works for virtually all use cases.

How Apache Chooses Which Virtual Host to Use

When a request arrives, Apache looks at the Host header (for HTTP/1.1 and later) and matches it against the ServerName and ServerAlias directives in your virtual host blocks. The matching logic is:

  1. If the request’s Host header matches exactly the ServerName of a virtual host, that host is used.
  2. If no exact match, Apache checks ServerAlias entries (wildcards like *.example.com also work).
  3. If still no match, the first virtual host defined in the configuration file is used as the default. This is important: the first block is the catch-all, so make it your main site or a placeholder page.

This order means you can have multiple domains pointing to the same IP, and Apache will serve the right content as long as each domain is listed in a <VirtualHost> block.

Setting Up Name-Based Virtual Hosts

Here is a minimal configuration for two sites on Ubuntu/Debian (paths may differ on other distributions). The steps assume you have Apache already installed and your DNS records point both domains to your server’s IP.

  1. Create the document roots and add a simple index.html to each so you can test later:
    sudo mkdir -p /var/www/site1/public_html
    sudo mkdir -p /var/www/site2/public_html
    echo '<h1>Site One</h1>' | sudo tee /var/www/site1/public_html/index.html
    echo '<h1>Site Two</h1>' | sudo tee /var/www/site2/public_html/index.html
  2. Create a configuration file for each site in /etc/apache2/sites-available/ (on RHEL/CentOS it’s /etc/httpd/conf.d/). For example, site1.conf:
    <VirtualHost *:80>
    ServerName www.site1.com
    ServerAlias site1.com
    DocumentRoot /var/www/site1/public_html
    ErrorLog ${APACHE_LOG_DIR}/site1_error.log
    CustomLog ${APACHE_LOG_DIR}/site1_access.log combined
    </VirtualHost>
  3. Enable the sites and reload Apache:
    sudo a2ensite site1.conf
    sudo a2ensite site2.conf
    sudo systemctl reload apache2

    On RHEL-based systems, you may need to restart httpd instead.

  4. Test by visiting http://site1.com and http://site2.com in a browser. If you haven’t updated DNS yet, you can edit your local /etc/hosts file to point the domains to your server’s IP for testing.

That’s the core. For HTTPS, you would add <VirtualHost *:443> blocks with the same ServerName and include the SSL certificate paths. Many people use a tool like Certbot to automate certificate issuance and Apache configuration for HTTPS.

Common Pitfalls and Troubleshooting

Even with a correct configuration, things can go wrong. Here are the most frequent issues:

  • The wrong site shows up. This usually means the Host header didn’t match any ServerName or ServerAlias, so Apache used the first virtual host. Double-check your ServerName spelling and ensure you have a ServerAlias for the bare domain (without www) if you want both to work.
  • Permission denied errors. Apache runs as the www-data user (on Debian/Ubuntu) or apache (on RHEL). Ensure the document root directories are readable by that user. Use sudo chown -R www-data:www-data /var/www/site1 or set appropriate permissions.
  • Configuration syntax errors. Run sudo apachectl configtest before reloading to catch typos. A single missing </VirtualHost> can break the whole server.
  • Port conflicts. If you are running another web server (like Nginx) on port 80, Apache won’t start. Check with sudo netstat -tulpn | grep :80.

Virtual Hosts vs. Other Approaches

Virtual hosts are not the only way to serve multiple sites. Here’s a quick comparison:

  • Separate servers or containers: Each site runs in its own VM or Docker container. This gives better isolation but uses more resources and is more complex to manage.
  • Reverse proxy (Nginx, HAProxy): A front-end server routes requests to backend servers based on the domain. This is common when you have multiple application servers (e.g., Node.js, Python) that don’t handle static files well.
  • Subdirectories vs. subdomains: You could put all sites under one domain (e.g., example.com/site1) but that mixes content and makes it harder to manage separate SSL certificates or redirects. Virtual hosts keep each site independent.

For most small-to-medium setups, Apache virtual hosts are the simplest and most reliable method.

Security and Performance Considerations

When hosting multiple sites, security becomes more critical because a compromise in one site could affect the others. Here are some best practices:

  • Run each site with its own user. Using Apache’s mod_ruid2 or mod_php with per-vhost PHP-FPM pools can isolate file permissions.
  • Keep software up to date. Especially if you run PHP, ensure you are using a supported version and apply security patches.
  • Use HTTPS everywhere. With free certificates from Let’s Encrypt, there’s no reason not to. Redirect HTTP to HTTPS in each virtual host.
  • Limit resource usage. If one site gets a traffic spike, it could exhaust Apache’s worker threads. Consider setting MaxRequestWorkers and per-vhost limits with mod_evasive or similar.
  • Log separately. As shown in the example, give each site its own error and access logs. This makes debugging and monitoring much easier.

Frequently Asked Questions

Do I need a separate IP address for each website?
No. Name-based virtual hosts use the domain name in the request, so all sites can share one IP address. This is the default and works for the vast majority of websites.

Can I use wildcard subdomains?
Yes. You can set ServerAlias *.example.com in a virtual host to catch all subdomains. This is handy for multi-tenant apps or for creating user subdomains on the fly.

What happens if someone accesses the server by its IP address?
Apache will serve the first virtual host defined in the configuration. To avoid exposing an unintended site, you can create a default virtual host that returns a 404 or a simple message.

How do I set up HTTPS for each site?
You need a certificate for each domain. With Let’s Encrypt, you can run certbot --apache and it will automatically create the SSL virtual hosts and set up renewal. For wildcard certificates, you’ll need DNS-based validation.

Why is my second site showing the first site’s content?
This almost always means the ServerName in the second virtual host doesn’t match the domain you’re typing. Check for typos, and remember that the first virtual host is the default for any unmatched request.

Can I host sites on different ports?
Yes, you can define virtual hosts on ports like 8080 or 8443, but users would need to include the port in the URL. It’s more common to use the standard ports (80 and 443) with name-based hosting.

Related

Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.

More cards in this drawer

The whole Numbers and Powers drawer →