The Best Price for IPv4/IPv6 Lease – Any RIR & Any Geo-LocationOrder Now
Hostperl

Configure Apache Virtual Hosts on Ubuntu 24.04 VPS

By Raman Kumar

Share:

Updated on Jun 25, 2026

Configure Apache Virtual Hosts on Ubuntu 24.04 VPS

Why Virtual Hosts Matter on a VPS

One of the first things most VPS customers want to do after provisioning a server is host more than one website on it. Buying a separate server for each domain would be expensive and wasteful. Apache's virtual host system solves this neatly — you define separate site configurations, and Apache routes each incoming request to the right document root based on the domain name.

This tutorial walks through the full setup on Ubuntu 24.04 LTS, covering installation, directory structure, virtual host files, DNS basics, and SSL. If you're migrating from shared hosting or a cPanel environment, this is roughly what happens under the hood when you add a new domain. On a Hostperl VPS, you'll have full root access to configure everything exactly as shown below.

Before You Begin

You'll need:

  • Ubuntu 24.04 LTS VPS with root or sudo access
  • At least two domain names pointing to your server's IP (or test using /etc/hosts locally)
  • Apache 2.4 installed (covered in step one)

All commands below assume you're logged in as a non-root user with sudo privileges. If you're still running as root directly, the commands work the same — just drop the sudo prefix.

Step 1: Install Apache

Start with a package index refresh, then install Apache:

sudo apt update
sudo apt install apache2 -y

Once it finishes, verify the service is running:

sudo systemctl status apache2

You should see active (running). Apache 2.4.58 ships with Ubuntu 24.04 and is the version this guide targets. If you visit your server's IP in a browser right now, you'll see the default Ubuntu Apache welcome page — that's the fallback virtual host, and it confirms Apache is answering requests.

Open the firewall for HTTP and HTTPS before going further:

sudo ufw allow 'Apache Full'
sudo ufw enable

Step 2: Create Directory Structure for Each Site

Apache needs a document root for each domain. A clean convention is to keep sites under /var/www/. For this tutorial, we'll use site1.com and site2.com as example domains — replace these with your actual domain names.

sudo mkdir -p /var/www/site1.com/public_html
sudo mkdir -p /var/www/site2.com/public_html

Set ownership so your regular user can write files without sudo every time:

sudo chown -R $USER:$USER /var/www/site1.com/public_html
sudo chown -R $USER:$USER /var/www/site2.com/public_html

Set standard permissions on the web root directories:

sudo chmod -R 755 /var/www

Now drop a quick index page into each so you can confirm routing is working later:

echo '<h1>site1.com is working</h1>' > /var/www/site1.com/public_html/index.html
echo '<h1>site2.com is working</h1>' > /var/www/site2.com/public_html/index.html

Step 3: Create Virtual Host Configuration Files

Apache on Ubuntu stores individual site configs in /etc/apache2/sites-available/. Each file is a plain text configuration. The default site lives in 000-default.conf — your new sites get their own files.

Create the config for site1.com:

sudo nano /etc/apache2/sites-available/site1.com.conf

Paste in this configuration:

<VirtualHost *:80>
    ServerName site1.com
    ServerAlias www.site1.com
    DocumentRoot /var/www/site1.com/public_html
    ErrorLog ${APACHE_LOG_DIR}/site1.com_error.log
    CustomLog ${APACHE_LOG_DIR}/site1.com_access.log combined
</VirtualHost>

Save and close (Ctrl+X, then Y, then Enter). Now create the same for site2.com:

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
    ErrorLog ${APACHE_LOG_DIR}/site2.com_error.log
    CustomLog ${APACHE_LOG_DIR}/site2.com_access.log combined
</VirtualHost>

Separate log files per domain is not just tidy — it makes troubleshooting much faster. When a client reports a 500 error on one site, you don't have to sift through a combined log to find the relevant entries.

Step 4: Enable the New Sites

Ubuntu uses a2ensite and a2dissite to manage which configs Apache actually loads. Enable both new sites:

sudo a2ensite site1.com.conf
sudo a2ensite site2.com.conf

Optionally disable the default fallback site if you don't need it:

sudo a2dissite 000-default.conf

Test your configuration syntax before reloading. This step has saved many people from an unexpected outage:

sudo apache2ctl configtest

You should see Syntax OK. If you see any errors, Apache will tell you the file and line number. Fix those before proceeding. Once it's clean, reload Apache to apply changes:

sudo systemctl reload apache2

Step 5: Verify DNS or Test Locally

For the virtual hosts to work from a browser, your domain names need A records pointing to the server's public IP. Log into your domain registrar or DNS provider and add:

  • site1.com → A record → your server IP
  • www.site1.com → A record → your server IP
  • Repeat for site2.com

DNS propagation typically takes a few minutes to a few hours. If you want to test immediately without waiting for DNS, add entries to your local machine's /etc/hosts file (Linux/macOS) or C:\Windows\System32\drivers\etc\hosts (Windows):

203.0.113.45  site1.com www.site1.com
203.0.113.45  site2.com www.site2.com

Replace 203.0.113.45 with your actual server IP. Open both domains in a browser and you should see the respective index pages you created in step two.

If you're planning a migration from shared hosting, it's worth reading through the website migration checklist for shared hosting to VPS before pointing live DNS records at your new server.

Step 6: Add SSL with Let's Encrypt

Running sites over plain HTTP in 2026 is not acceptable for production. Certbot makes SSL free and largely automatic. Install it with the Apache plugin:

sudo apt install certbot python3-certbot-apache -y

Request certificates for both domains in one command:

sudo certbot --apache -d site1.com -d www.site1.com -d site2.com -d www.site2.com

Certbot will prompt for an email address for expiry notifications, ask you to agree to the terms of service, and then contact Let's Encrypt to validate domain ownership. It rewrites your virtual host configs automatically to handle HTTPS on port 443 and redirect HTTP to HTTPS.

For a deeper look at how to handle certificates when you're running multiple domains across different configurations, the tutorial on configuring multi-domain SSL on Ubuntu VPS with Certbot covers edge cases and renewal automation in detail.

Verify auto-renewal is active:

sudo systemctl status certbot.timer

Certbot installs a systemd timer that checks for near-expiry certificates twice daily and renews them automatically. You shouldn't need to think about it again.

Step 7: Common Configuration Additions

A basic virtual host block works, but most real sites need a few extra directives. Here are the most common ones you'll add over time.

Directory Options and .htaccess

If you're running WordPress or any CMS that uses pretty URLs, you need to allow .htaccess overrides. Add this inside your VirtualHost block:

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

Also enable mod_rewrite, which most CMS platforms depend on:

sudo a2enmod rewrite
sudo systemctl reload apache2

Custom Error Pages

A generic Apache 404 page looks unprofessional. Add a custom one inside the virtual host block:

ErrorDocument 404 /404.html
ErrorDocument 500 /500.html

Place the corresponding HTML files in your document root.

Redirecting Non-WWW to WWW

If you want all traffic to land on www.site1.com rather than splitting between the bare domain and www, add a separate redirect block:

<VirtualHost *:80>
    ServerName site1.com
    Redirect permanent / http://www.site1.com/
</VirtualHost>

With SSL in place, Certbot handles the HTTP-to-HTTPS redirect, but you still control the www vs non-www preference in your config.

Troubleshooting: What to Check When a Site Won't Load

Virtual host issues usually come down to a small set of problems. Work through this list before digging deeper:

  1. Config syntax error — run sudo apache2ctl configtest and fix any reported issues.
  2. Apache not reloaded — changes only take effect after sudo systemctl reload apache2.
  3. Wrong ServerName — check that the domain in your browser exactly matches ServerName or ServerAlias in the config.
  4. DNS not propagated — use dig site1.com +short to confirm the A record resolves to your server IP.
  5. Firewall blocking port 80 or 443 — run sudo ufw status and confirm Apache Full is listed as allowed.
  6. Permission errors — check that the Apache user (www-data) can read the document root: ls -la /var/www/site1.com/.

Check the site-specific error log for anything the above steps don't catch:

sudo tail -50 /var/log/apache2/site1.com_error.log

If your setup also involves PHP applications across sites, the tutorial on configuring multi-PHP versions on Ubuntu VPS with Apache shows how to assign different PHP versions per virtual host, which is particularly useful when running a mix of older and newer applications.

For broader security hardening beyond just the web server config, the VPS security checklist for 2026 is a practical companion to this tutorial.

Ready to host multiple sites on your own server? Hostperl VPS plans include full root access, SSD storage, and Ubuntu 24.04 as a one-click install — everything you need to follow this guide from scratch. Need more headroom for high-traffic sites? Our dedicated server hosting gives you isolated resources and no noisy neighbours. Our support team is available to assist with initial setup if you get stuck.

Frequently Asked Questions

How many virtual hosts can Apache handle on one VPS?

There's no hard limit built into Apache. The practical ceiling depends on your server's RAM, CPU, and traffic. A VPS with 2GB RAM can comfortably serve dozens of low-traffic sites. High-traffic sites each need their own resources and may eventually warrant a dedicated server.

Does each virtual host need its own SSL certificate?

Not necessarily. Certbot and Let's Encrypt support Subject Alternative Names (SANs), so one certificate can cover multiple domains. You can also use wildcard certificates for all subdomains of a single domain. The Certbot command in step six already handles multiple domains in a single certificate request.

Can I use IP-based virtual hosts instead of name-based?

Yes, but it requires one IP address per site. Name-based virtual hosting (what this guide uses) is almost always the right choice — it works with a single IP, which is simpler and cheaper. IP-based hosting is mainly relevant for legacy SSL setups before SNI became universal, which is no longer a concern.

My site loads the wrong virtual host. What went wrong?

Apache serves the first enabled virtual host alphabetically if it can't match a ServerName. Double-check your config file's ServerName matches the domain exactly, and confirm the site is enabled with sudo a2ensite yoursite.conf followed by a reload. Running apache2ctl -S shows a summary of all active virtual hosts and their matched ports — helpful for spotting conflicts.