// Blog

How to Install and Configure Apache2 with Virtual Hosts on a Linux VPS: Complete Guide

October 04, 2026 · by Alex M.

How to Install and Configure Apache2 with Virtual Hosts on a Linux VPS: Complete Guide

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.

What Are Virtual Hosts and Why Do You Need Them?

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:

  • Name-based Virtual Hosts — sites are differentiated by domain name (most common)
  • IP-based Virtual Hosts — each site gets its own dedicated IP address

This guide focuses on name-based virtual hosts, which work perfectly for the vast majority of production scenarios.

Prerequisites

Before starting, make sure you have:

  • A VPS running Ubuntu 22.04 (or Debian 11/12)
  • Root access or a user with sudo privileges
  • At least one registered domain with DNS pointing to your server's IP
  • An active SSH connection

If you don't have a server yet, you can spin up a NVMe VPS at CLIQHOST — ready in minutes with full root access.

Step 1: Update the System and Install Apache2

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

Firewall Configuration (UFW)

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.

Step 2: Set Up the Directory Structure for Virtual Hosts

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.

Step 3: Create Virtual Host Configuration Files

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>

Enabling Virtual Hosts

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

Step 4: Enable Essential Apache2 Modules

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

Why Does 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.

Step 5: Hardening Apache2 Security

A web server exposed to the internet needs proper hardening. Here are the essential configurations.

Hide the Apache2 Version

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.

Disable Directory Listing

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

Add Security HTTP Headers

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>

Restrict Allowed HTTP Methods

<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.

Step 6: Installing SSL with Let's Encrypt (HTTPS)

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.

Step 7: Performance Optimization

Configure the MPM (Multi-Processing Module)

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.

Enable GZIP Compression

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>

Browser Caching for Static Assets

<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.

Step 8: Log Management

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.

Apache2 Quick Reference — Essential Commands

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 Troubleshooting

403 Forbidden Error

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

404 Not Found Error

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.

Apache2 Won't Start

Check the logs:

sudo journalctl -xe | grep apache2
sudo tail -50 /var/log/apache2/error.log

Port 80 Already in Use

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.

Conclusion

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.

SHARE
// what clients say

What Our Clients Say

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."

AM
Andrei M.
eCommerce owner · Chișinău
★★★★★

"Migrated 12 client sites to CLIQHOST. Free migration, zero downtime, and the cPanel setup is exactly what my team needed. Highly recommend."

EV
Elena V.
Web agency · Bălți
★★★★★

"Our NVMe VPS handles traffic spikes without a sweat. Full root, local datacenter, and billing in MDL — everything we wanted from a provider."

DC
Dmitri C.
SaaS founder · Chișinău