Apache Virtual Hosts Setup for Multiple Domains on VPS

Apache Virtual Hosts Setup for Multiple Domains

June 2026 · 7 min read

Apache Virtual Hosts allow a single VPS to host multiple websites on one IP address. Each domain has its own document root, configuration, and SSL certificate. This is essential knowledge before deploying multiple websites on a single VPS server.

Install Apache

sudo apt update
sudo apt install apache2 -y
sudo systemctl enable --now apache2

Create Virtual Hosts

# Create document root
sudo mkdir -p /var/www/example.com/public_html
sudo chown -R $USER:www-data /var/www/example.com
sudo chmod -R 755 /var/www/example.com

# Create test index page
echo "

example.com is working

" > /var/www/example.com/public_html/index.html
# Create virtual host config
sudo nano /etc/apache2/sites-available/example.com.conf
<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /var/www/example.com/public_html

    <Directory /var/www/example.com/public_html>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/example.com-error.log
    CustomLog ${APACHE_LOG_DIR}/example.com-access.log combined
</VirtualHost>
# Enable site
sudo a2ensite example.com.conf
sudo a2enmod rewrite  # for .htaccess redirects
sudo systemctl reload apache2

Add SSL with Let's Encrypt

sudo apt install certbot python3-certbot-apache -y

# Issue certificate (DNS must point to VPS first)
sudo certbot --apache -d example.com -d www.example.com

# Certbot automatically updates config with HTTPS redirect and SSL settings
# View the updated config
cat /etc/apache2/sites-available/example.com-le-ssl.conf

Separate PHP-FPM Pool Per Virtual Host

For better security, running a separate PHP-FPM pool for each website is recommended instead of using a shared pool:

sudo apt install php8.3-fpm -y
sudo a2enmod proxy_fcgi setenvif
sudo a2enconf php8.3-fpm

# Add inside VirtualHost block:
<FilesMatch \.php$>
    SetHandler "proxy:unix:/run/php/php8.3-fpm.sock|fcgi://localhost"
</FilesMatch>
Tip: Create a separate PHP-FPM pool for each site by copying /etc/php/8.3/fpm/pool.d/www.conf with the site name, then change the user, group, and listen socket. This ensures each site's PHP runs under its own user account.

Verify Virtual Host is Working Correctly

# Check config syntax
sudo apache2ctl configtest

# View active virtual hosts
sudo apache2ctl -S

# Test with curl
curl -H "Host: example.com" http://localhost

# Check error logs
sudo tail -f /var/log/apache2/example.com-error.log
Tip: apache2ctl -S displays all virtual hosts with their ports and DocumentRoot, helping you debug which vhost a request is being routed to.

Common Issues & Troubleshooting

Seeing Apache Default Page Instead of Your Site

The default site is still active or the ServerName doesn't match the request DNS. Disable the default site:

sudo a2dissite 000-default.conf
sudo systemctl reload apache2

# Check vhost matching
sudo apache2ctl -S | grep "example.com"

403 Forbidden When Accessing the Site

Directory permissions are incorrect or AllowOverride is not set properly:

# Check permissions
ls -la /var/www/example.com/public_html/

# Fix permissions
sudo chown -R www-data:www-data /var/www/example.com
sudo chmod -R 755 /var/www/example.com

# Check SELinux (if enabled)
ls -laZ /var/www/example.com/

.htaccess Not Working

AllowOverride must be set to All and mod_rewrite must be enabled:

sudo a2enmod rewrite
sudo systemctl reload apache2

# Check AllowOverride in config
grep -r "AllowOverride" /etc/apache2/sites-enabled/

SSL Certificate from One Site Used for Another

Apache uses SNI to select the correct certificate based on ServerName. Verify the ServerName in your SSL config is correct:

# View SSL virtual hosts
sudo apache2ctl -S | grep "*:443"

# Check which certificate the site is using
echo | openssl s_client -servername example.com -connect localhost:443 2>/dev/null | openssl x509 -noout -subject

Frequently Asked Questions

Is Apache or Nginx Better for Virtual Hosting?

Both support virtual hosting well. Nginx uses less memory and is better suited for static files and reverse proxies. Apache excels with .htaccess support, which many PHP applications and WordPress installations rely on. If you're hosting many PHP-based applications that need .htaccess, Apache is more convenient.

How Many Domains Can Run on a Single VPS?

Theoretically unlimited, but constrained by RAM and CPU. A 1GB RAM VPS can comfortably run 10-20 WordPress sites with low traffic. However, if your sites have high traffic, you need to ensure sufficient resources are available for all sites.

Can Each Virtual Host Have Separate Logs?

Yes, each VirtualHost block can have separate ErrorLog and CustomLog directives, making it easy to debug individual sites without filtering through combined logs. You should set separate logs for every site.