
Understanding Apache Virtual Hosts on VPS Hosting
Apache virtual hosts let you run multiple websites from a single VPS server. Each domain gets its own document root, configuration, and log files. All sites share the same Apache installation.
This setup maximizes server resources and simplifies management for hosting multiple sites.
Virtual hosts work through name-based or IP-based routing. Name-based virtual hosts examine the HTTP Host header to determine which site to serve. IP-based virtual hosts bind different domains to separate IP addresses.
Most VPS configurations use name-based virtual hosts. They're more flexible and don't require multiple IP addresses.
The configuration process involves creating virtual host files, enabling sites, and managing DNS records. Ubuntu's Apache package includes helpful tools like a2ensite and a2dissite that streamline virtual host management.
Prerequisites and Server Preparation
Your Ubuntu VPS needs Apache 2.4 or later installed and running. Check your version with apache2 -v.
Install Apache if it's missing:
sudo apt update
sudo apt install apache2
Enable Apache to start automatically:
sudo systemctl enable apache2
sudo systemctl start apache2
Verify Apache is running by checking port 80:
sudo netstat -tlnp | grep :80
You'll also need root access or sudo privileges. Create a non-root user with sudo access if you're currently using the root account.
Domain names should point to your VPS IP address through A records in your DNS configuration.
For HostMyCode VPS customers, Apache comes pre-configured in our LAMP stack images. This saves you the initial installation steps.
Creating Your First Apache Virtual Hosts Configuration
Navigate to the Apache sites-available directory where virtual host configurations live:
cd /etc/apache2/sites-available/
Create a new configuration file for your domain. Replace example.com with your actual domain:
sudo nano example.com.conf
Add this basic virtual host configuration:
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example.com
ErrorLog ${APACHE_LOG_DIR}/example.com_error.log
CustomLog ${APACHE_LOG_DIR}/example.com_access.log combined
</VirtualHost>
The ServerName directive sets the primary domain name. ServerAlias handles the www version. DocumentRoot points to your website files.
Error and access logs get separate files for easier troubleshooting.
Create the document root directory:
sudo mkdir -p /var/www/example.com
sudo chown -R www-data:www-data /var/www/example.com
sudo chmod -R 755 /var/www/example.com
Add a test HTML file to verify the setup:
echo "<h1>Welcome to example.com</h1>" | sudo tee /var/www/example.com/index.html
Enabling Virtual Hosts and Testing Configuration
Enable your new virtual host with Apache's site management tools:
sudo a2ensite example.com.conf
Test the Apache configuration for syntax errors:
sudo apache2ctl configtest
You should see "Syntax OK" if everything is correct. Common errors include missing closing tags, invalid directive names, or incorrect file paths.
Reload Apache to apply the new configuration:
sudo systemctl reload apache2
Verify the site loads correctly by visiting your domain in a browser. If you're testing before DNS propagation, add the domain to your local hosts file temporarily.
Check the Apache error log if the site doesn't load:
sudo tail -f /var/log/apache2/example.com_error.log
Multiple Domain Configuration
Adding more domains follows the same pattern. Create another configuration file:
sudo nano /etc/apache2/sites-available/seconddomain.com.conf
Use a similar structure with different paths:
<VirtualHost *:80>
ServerName seconddomain.com
ServerAlias www.seconddomain.com
DocumentRoot /var/www/seconddomain.com
ErrorLog ${APACHE_LOG_DIR}/seconddomain.com_error.log
CustomLog ${APACHE_LOG_DIR}/seconddomain.com_access.log combined
</VirtualHost>
Create the document root and set permissions:
sudo mkdir -p /var/www/seconddomain.com
sudo chown -R www-data:www-data /var/www/seconddomain.com
sudo chmod -R 755 /var/www/seconddomain.com
Enable the site and reload Apache:
sudo a2ensite seconddomain.com.conf
sudo apache2ctl configtest
sudo systemctl reload apache2
Each domain operates independently with separate log files and document roots. This isolation prevents one site from affecting another and simplifies maintenance.
SSL Certificate Configuration with Let's Encrypt
Secure your virtual hosts with free SSL certificates from Let's Encrypt. Install Certbot first:
sudo apt install certbot python3-certbot-apache
Request certificates for your domains:
sudo certbot --apache -d example.com -d www.example.com
Certbot automatically modifies your virtual host configurations to include SSL settings. The updated configuration will look like this:
<VirtualHost *:443>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example.com
ErrorLog ${APACHE_LOG_DIR}/example.com_error.log
CustomLog ${APACHE_LOG_DIR}/example.com_access.log combined
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
</VirtualHost>
Test automatic certificate renewal:
sudo certbot renew --dry-run
The renewal process runs automatically via systemd timer. Check the timer status:
sudo systemctl status certbot.timer
For detailed SSL configuration guidance, review our Linux VPS SSL setup tutorial. It covers advanced security headers and cipher configurations.
Advanced Virtual Host Security Configuration
Enhance your virtual host security with additional directives. Add these settings inside each VirtualHost block:
<Directory "/var/www/example.com">
Options -Indexes -ExecCGI
AllowOverride None
Require all granted
</Directory>
# Disable server signature
ServerTokens Prod
ServerSignature Off
# Security headers
Header always set X-Content-Type-Options nosniff
Header always set X-Frame-Options DENY
Header always set X-XSS-Protection "1; mode=block"
The Options -Indexes directive prevents directory browsing when no index file exists. -ExecCGI disables CGI script execution unless specifically configured.
Enable the headers module to use security headers:
sudo a2enmod headers
sudo systemctl reload apache2
Create custom error pages to avoid revealing server information:
ErrorDocument 404 /404.html
ErrorDocument 403 /403.html
ErrorDocument 500 /500.html
Disable unnecessary HTTP methods:
<LimitExcept GET POST HEAD>
Require all denied
</LimitExcept>
Performance Optimization and Caching
Enable Apache modules that improve virtual host performance:
sudo a2enmod deflate
sudo a2enmod expires
sudo a2enmod headers
sudo a2enmod rewrite
Add compression and caching directives to your virtual host:
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/x-javascript
</IfModule>
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpg "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/pdf "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
ExpiresByType application/x-javascript "access plus 1 month"
ExpiresByType text/html "access plus 2 days"
</IfModule>
Configure KeepAlive settings in the main Apache configuration for better connection handling:
sudo nano /etc/apache2/apache2.conf
Add or modify these settings:
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5
Monitoring and Log Management
Each virtual host generates separate log files in /var/log/apache2/. Monitor these logs for errors, security issues, and traffic patterns.
View real-time access logs:
sudo tail -f /var/log/apache2/example.com_access.log
Search for specific error patterns:
sudo grep "404" /var/log/apache2/example.com_access.log
Configure log rotation to prevent disk space issues:
sudo nano /etc/logrotate.d/apache2
The default configuration rotates logs weekly and keeps four weeks of history. Adjust these settings based on your traffic volume and storage capacity.
Set up log shipping to centralize monitoring across multiple virtual hosts. Our VPS log shipping guide covers rsyslog configuration for centralized logging.
Troubleshooting Common Virtual Host Issues
When virtual hosts don't work correctly, start with these diagnostic steps.
Check if the site is enabled:
sudo apache2ctl -S
This command lists all virtual hosts and their configurations. Look for your domain in the output.
Verify DNS resolution:
nslookup example.com
dig example.com A
The domain should resolve to your VPS IP address. DNS propagation can take up to 24 hours for new domains.
Test Apache configuration syntax:
sudo apache2ctl configtest
Common configuration errors include:
- Missing ServerName directive
- Incorrect DocumentRoot path
- Missing closing VirtualHost tag
- Permission issues with document root
Check file permissions on the document root:
ls -la /var/www/example.com
The directory should be owned by www-data with 755 permissions. HTML files should have 644 permissions.
If one virtual host works but others don't, compare their configurations. Look for differences in syntax or directory structure.
Running multiple websites on a single server requires reliable VPS hosting with adequate resources. HostMyCode VPS plans include pre-configured LAMP stacks and full root access for Apache virtual host management. Our managed VPS hosting handles server maintenance so you can focus on your websites.
Frequently Asked Questions
How many virtual hosts can I run on one VPS?
The limit depends on your VPS resources and website traffic. A 2GB RAM VPS can typically handle 10-20 low-traffic sites. Monitor CPU usage, memory consumption, and disk I/O to determine your optimal capacity.
Can I use different PHP versions for different virtual hosts?
Yes, configure PHP-FPM with separate pools for each domain. Create custom PHP-FPM pool configurations and specify the PHP version in each virtual host using SetHandler directives.
What happens if two virtual hosts have the same ServerName?
Apache uses the first matching virtual host configuration. Avoid duplicate ServerName directives to prevent unexpected behavior. Use ServerAlias for additional domain variations.
How do I redirect HTTP to HTTPS for all virtual hosts?
Add a global redirect in the main Apache configuration or create separate HTTP virtual hosts that redirect to HTTPS versions. Certbot automatically creates these redirects when installing SSL certificates.
Can I use wildcard SSL certificates with Apache virtual hosts?
Yes, wildcard certificates work with subdomain virtual hosts. Configure the certificate path in each virtual host that uses the same root domain. One certificate can secure multiple subdomains.