October 04, 2026 · by Alex M.
Apache2 is one of the most battle-tested and widely deployed web servers in the world. Its modular architecture, rich documentation, and broad community support make it a top choice for hosting anything from small personal sites to large production applications. If you have a NVMe VPS and want to host multiple websites on a single server, Apache2's Virtual Hosts feature is the clean, efficient solution you need. This guide walks you through everything — from installation to performance tuning — on Ubuntu 22.04.
Virtual Hosts allow you to run multiple websites on one server sharing a single IP address, each with its own domain, configuration, and file directory. For example, on a single SSD VPS you can simultaneously host site1.com, site2.com, and blog.mycompany.com without any additional infrastructure cost.
There are two main types:
This guide focuses on name-based virtual hosts, which work perfectly for the vast majority of production scenarios.
Before starting, make sure you have:
sudo privilegesIf you don't have a server yet, you can spin up a NVMe VPS at CLIQHOST — ready in minutes with full root access.
Connect to your server via SSH and update the package list:
sudo apt update && sudo apt upgrade -y
Install Apache2:
sudo apt install apache2 -y
Check the service status:
sudo systemctl status apache2
You should see active (running). Enable Apache2 to start automatically on reboot:
sudo systemctl enable apache2
If you're using UFW, allow HTTP and HTTPS traffic:
sudo ufw allow 'Apache Full'
sudo ufw status
Now if you open your server's IP in a browser, you should see the default Apache2 welcome page.
By convention, each website gets its own directory under /var/www/. Let's create the structure for two demo sites:
sudo mkdir -p /var/www/site1.com/public_html
sudo mkdir -p /var/www/site2.com/public_html
Assign ownership to your current user:
sudo chown -R $USER:$USER /var/www/site1.com/public_html
sudo chown -R $USER:$USER /var/www/site2.com/public_html
Set the correct permissions:
sudo chmod -R 755 /var/www/site1.com
sudo chmod -R 755 /var/www/site2.com
Create test HTML pages:
nano /var/www/site1.com/public_html/index.html
Example content:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Site1.com</title>
</head>
<body>
<h1>Welcome to site1.com!</h1>
<p>Apache2 Virtual Host is working correctly.</p>
</body>
</html>
Repeat for site2.com.
Apache2 stores site configurations in /etc/apache2/sites-available/. There's a default 000-default.conf file you can use as a template.
Create the configuration for the first site:
sudo nano /etc/apache2/sites-available/site1.com.conf
Full content:
<VirtualHost *:80>
ServerAdmin [email protected]
ServerName site1.com
ServerAlias www.site1.com
DocumentRoot /var/www/site1.com/public_html
<Directory /var/www/site1.com/public_html>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/site1.com-error.log
CustomLog ${APACHE_LOG_DIR}/site1.com-access.log combined
</VirtualHost>
Create the configuration for the second site:
sudo nano /etc/apache2/sites-available/site2.com.conf
<VirtualHost *:80>
ServerAdmin [email protected]
ServerName site2.com
ServerAlias www.site2.com
DocumentRoot /var/www/site2.com/public_html
<Directory /var/www/site2.com/public_html>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/site2.com-error.log
CustomLog ${APACHE_LOG_DIR}/site2.com-access.log combined
</VirtualHost>
Enable the new sites and disable the default one (optional):
sudo a2ensite site1.com.conf
sudo a2ensite site2.com.conf
sudo a2dissite 000-default.conf
Test the configuration syntax:
sudo apache2ctl configtest
You should see Syntax OK. Reload Apache2:
sudo systemctl reload apache2
Apache2 ships with a rich set of modules. Here are the most useful ones for a production server:
# URL rewriting (required for WordPress, Joomla, etc.)
sudo a2enmod rewrite
# GZIP compression
sudo a2enmod deflate
# HTTP headers (security)
sudo a2enmod headers
# Caching
sudo a2enmod cache cache_disk
sudo systemctl restart apache2
rewrite Matter?Without mod_rewrite, WordPress pretty permalinks, .htaccess rules, and SEO-friendly URLs simply won't work. The AllowOverride All directive in your Virtual Host config allows Apache2 to read .htaccess files from the site's directory — this is essential for CMS-based sites.
A web server exposed to the internet needs proper hardening. Here are the essential configurations.
Edit the main security configuration file:
sudo nano /etc/apache2/conf-available/security.conf
Set:
ServerTokens Prod
ServerSignature Off
TraceEnable Off
This prevents Apache2 from exposing its version number in HTTP headers and error pages, reducing the attack surface.
If a directory has no index.html or index.php, Apache2 may expose the directory contents — a significant security risk. Make sure your Virtual Host config includes:
Options -Indexes
In the Virtual Host file or .htaccess:
<IfModule mod_headers.c>
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set X-XSS-Protection "1; mode=block"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
</IfModule>
<LimitExcept GET POST HEAD>
deny from all
</LimitExcept>
For advanced server hardening and ongoing monitoring, CLIQHOST's server management service handles everything from security audits to performance tuning.
Every modern website must run on HTTPS. Install Certbot:
sudo apt install certbot python3-certbot-apache -y
Obtain a free SSL certificate:
sudo certbot --apache -d site1.com -d www.site1.com
Certbot will automatically modify the Virtual Host file and set up HTTP → HTTPS redirection. Verify automatic renewal:
sudo certbot renew --dry-run
If you need a commercial SSL certificate with Organization Validation (OV) or Extended Validation (EV), CLIQHOST offers a full range of options for businesses that require the highest level of trust indicators.
Apache2 supports three MPM modules: prefork, worker, and event. For maximum performance with PHP-FPM, use event:
sudo a2dismod mpm_prefork
sudo a2enmod mpm_event
sudo systemctl restart apache2
mpm_event handles connections asynchronously, allowing far more concurrent connections with the same hardware resources.
Add to the Virtual Host config or .htaccess:
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/plain text/html text/css
AddOutputFilterByType DEFLATE application/javascript application/json
AddOutputFilterByType DEFLATE image/svg+xml application/xml
</IfModule>
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
</IfModule>
This dramatically reduces repeat-visitor load times by instructing browsers to cache static files locally.
Logs are essential for troubleshooting and security monitoring. Each Virtual Host has its own log files as defined in the config:
# Watch error logs in real time
sudo tail -f /var/log/apache2/site1.com-error.log
# Watch access logs
sudo tail -f /var/log/apache2/site1.com-access.log
Apache2 uses logrotate for automatic log rotation. The configuration is at /etc/logrotate.d/apache2. By default it rotates logs weekly and keeps 52 weeks of history.
| Command | Description |
|---|---|
sudo systemctl start apache2 |
Start the service |
sudo systemctl stop apache2 |
Stop the service |
sudo systemctl restart apache2 |
Full restart |
sudo systemctl reload apache2 |
Reload config without downtime |
sudo a2ensite name.conf |
Enable a Virtual Host |
sudo a2dissite name.conf |
Disable a Virtual Host |
sudo a2enmod module |
Enable a module |
sudo a2dismod module |
Disable a module |
sudo apache2ctl configtest |
Test configuration syntax |
sudo apache2ctl -M |
List active modules |
Common causes: wrong directory permissions, Options -Indexes with no index.html present, or AllowOverride None instead of All. Debug with:
ls -la /var/www/site1.com/public_html
sudo apache2ctl configtest
Check that ServerName and ServerAlias are set correctly and that your domain's DNS is pointing to the server's IP address. DNS propagation can take up to 24–48 hours.
Check the logs:
sudo journalctl -xe | grep apache2
sudo tail -50 /var/log/apache2/error.log
sudo ss -tlnp | grep :80
If Nginx is already running on port 80, you'll need to stop one service or configure Apache2 on an alternate port.
Apache2 with Virtual Hosts is a robust, flexible, and proven solution for hosting multiple websites on a single Linux VPS. In this guide you've covered the full stack: installation, Virtual Host configuration, enabling key modules, server hardening, SSL setup, and performance tuning.
For a reliable foundation to run this setup, explore our NVMe VPS plans and dedicated server options — delivering guaranteed performance, 24/7 technical support, and modern infrastructure.
Have questions or need help with your server configuration? Contact the CLIQHOST team or explore more practical Linux and hosting guides on our blog.
Real reviews from customers who trust CLIQHOST for performance, reliability and expert technical support.
"We moved our online shop from a foreign host and the difference is night and day — pages load instantly and support replies in minutes, in Romanian."
"Migrated 12 client sites to CLIQHOST. Free migration, zero downtime, and the cPanel setup is exactly what my team needed. Highly recommend."
"Our NVMe VPS handles traffic spikes without a sweat. Full root, local datacenter, and billing in MDL — everything we wanted from a provider."