How to Configure Apache Virtual Hosts for Multiple Sites
Apache Virtual Hosts allow you to run multiple websites on a single Breeze server, each with its own domain name, document root, and configuration. This is one of the most fundamental Apache features and is essential for hosting more than one site on a single IP address.
Prerequisites
- Apache installed on your Breeze instance (
sudo apt install apache2) - DNS A records for each domain pointing to your server IP
- Root or sudo access
Step 1: Create Directory Structure
Set up separate document roots for each site:
sudo mkdir -p /var/www/site1.com/public_html
sudo mkdir -p /var/www/site2.com/public_html
sudo chown -R www-data:www-data /var/www/site1.com
sudo chown -R www-data:www-data /var/www/site2.com
Create a test page for each site:
echo "<h1>Welcome to Site 1</h1>" | sudo tee /var/www/site1.com/public_html/index.html
echo "<h1>Welcome to Site 2</h1>" | sudo tee /var/www/site2.com/public_html/index.html
Step 2: Create Virtual Host Configuration Files
Apache on Debian/Ubuntu stores virtual host configs in /etc/apache2/sites-available/. Create a config for the first site:
sudo nano /etc/apache2/sites-available/site1.com.conf
<VirtualHost *:80>
ServerName site1.com
ServerAlias www.site1.com
DocumentRoot /var/www/site1.com/public_html
<Directory /var/www/site1.com/public_html>
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/site1-error.log
CustomLog ${APACHE_LOG_DIR}/site1-access.log combined
</VirtualHost>
Create the second site configuration:
sudo nano /etc/apache2/sites-available/site2.com.conf
<VirtualHost *:80>
ServerName site2.com
ServerAlias www.site2.com
DocumentRoot /var/www/site2.com/public_html
<Directory /var/www/site2.com/public_html>
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/site2-error.log
CustomLog ${APACHE_LOG_DIR}/site2-access.log combined
</VirtualHost>
Step 3: Enable the Sites
sudo a2ensite site1.com.conf
sudo a2ensite site2.com.conf
sudo a2dissite 000-default.conf
sudo apache2ctl configtest
sudo systemctl reload apache2
Step 4: Add SSL with Let's Encrypt
Install Certbot and obtain certificates for each site:
sudo apt install -y certbot python3-certbot-apache
sudo certbot --apache -d site1.com -d www.site1.com
sudo certbot --apache -d site2.com -d www.site2.com
Certbot automatically creates the SSL virtual host configs and sets up automatic renewal.
Advanced Configuration Options
You can enhance your virtual hosts with additional directives:
<VirtualHost *:443>
ServerName site1.com
DocumentRoot /var/www/site1.com/public_html
# Enable HTTP/2
Protocols h2 h2c http/1.1
# Security headers
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
# PHP-FPM integration
<FilesMatch \.php$>
SetHandler "proxy:unix:/var/run/php/php8.2-fpm.sock|fcgi://localhost"
</FilesMatch>
# Logging
ErrorLog ${APACHE_LOG_DIR}/site1-error.log
CustomLog ${APACHE_LOG_DIR}/site1-access.log combined
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/site1.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/site1.com/privkey.pem
</VirtualHost>
Troubleshooting
- All domains show the same site — check that
ServerNamematches the domain exactly and runapache2ctl -Sto list active virtual hosts - Forbidden errors — verify
Require all grantedis set in the Directory block and file permissions are correct - Modules not loaded — enable required modules with
a2enmod rewrite ssl headers proxy_fcgi - Config syntax errors — always run
apache2ctl configtestbefore reloading