Set up Apache virtual hosts on Ubuntu is one of the most powerful and commonly used features of the Apache HTTP Server, allowing a single server to host multiple websites or domains with completely separate content, configurations, and document roots.

In this complete 2025–2026 guide, you’ll learn exactly how to set up Apache virtual hosts on Ubuntu (22.04 LTS, 24.04 LTS, and later) step-by-step: create directory structures, set permissions, build virtual host config files, enable sites, test locally (even without real DNS), and verify everything works. By the end, one Ubuntu server will serve two (or more) independent sites.

Whether you’re hosting personal projects or production sites, mastering how to set up Apache virtual hosts on Ubuntu is a core skill every web administrator needs.

Key Takeaways – How to Set Up Apache Virtual Hosts on Ubuntu

  • Set up Apache virtual hosts on Ubuntu to host multiple domains on one server without interference.
  • Each virtual host needs its own directory under /var/www (e.g., /var/www/example.com/public_html).
  • Virtual host files live in /etc/apache2/sites-available/ and end in .conf (e.g., example.com.conf).
  • Use a2ensite to enable and a2dissite to disable sites; always reload Apache after changes.
  • Test locally by editing your computer’s hosts file to point domains to your server IP.
  • ServerName defines the primary domain; ServerAlias handles additional names (www, subdomains).
  • Use proper ownership (www-data or your user) and permissions (755 directories, 644 files).

Prerequisites – Set Up Apache Virtual Hosts on Ubuntu

  • Ubuntu server (22.04 LTS, 24.04 LTS, or later) with non-root sudo user
  • Apache installed (sudo apt install apache2)
  • Firewall enabled (UFW recommended)
  • Optional: Two domain names with A records pointing to your server IP (or test locally)

Step 1: Create Directory Structure for Each Site

Create a folder for each domain under /var/www:

				
					sudo mkdir -p /var/www/example.com/public_html
sudo mkdir -p /var/www/testsite.org/public_html
				
			

Replace example.com and testsite.org with your actual domains.

Step 2: Set Ownership and Permissions

Give your user ownership so you can edit files, and allow Apache (www-data) to read them:

				
					sudo chown -R $USER:$USER /var/www/example.com/public_html
sudo chown -R $USER:$USER /var/www/testsite.org/public_html

sudo chmod -R 755 /var/www
				
			

Step 3: Create Sample Index Pages

Create a basic index.html for each site:

For first site:

				
					nano /var/www/example.com/public_html/index.html
				
			
				
					<!DOCTYPE html>
<html>
<head><title>Welcome to example.com</title></head>
<body><h2>Success! example.com virtual host is working!</h2><script>(()=>{class RocketElementorPreload{constructor(){this.deviceMode=document.createElement("span"),this.deviceMode.id="elementor-device-mode-wpr",this.deviceMode.setAttribute("class","elementor-screen-only"),document.body.appendChild(this.deviceMode)}t(){let t=getComputedStyle(this.deviceMode,":after").content.replace(/"/g,"");this.animationSettingKeys=this.i(t),document.querySelectorAll(".elementor-invisible[data-settings]").forEach((t=>{const e=t.getBoundingClientRect();if(e.bottom>=0&&e.top<=window.innerHeight)try{this.o(t)}catch(t){}}))}o(t){const e=JSON.parse(t.dataset.settings),i=e.m||e.animation_delay||0,n=e[this.animationSettingKeys.find((t=>e[t]))];if("none"===n)return void t.classList.remove("elementor-invisible");t.classList.remove(n),this.currentAnimation&&t.classList.remove(this.currentAnimation),this.currentAnimation=n;let o=setTimeout((()=>{t.classList.remove("elementor-invisible"),t.classList.add("animated",n),this.l(t,e)}),i);window.addEventListener("rocket-startLoading",(function(){clearTimeout(o)}))}i(t="mobile"){const e=[""];switch(t){case"mobile":e.unshift("_mobile");case"tablet":e.unshift("_tablet");case"desktop":e.unshift("_desktop")}const i=[];return["animation","_animation"].forEach((t=>{e.forEach((e=>{i.push(t+e)}))})),i}l(t,e){this.i().forEach((t=>delete e[t])),t.dataset.settings=JSON.stringify(e)}static run(){const t=new RocketElementorPreload;requestAnimationFrame(t.t.bind(t))}}document.addEventListener("DOMContentLoaded",RocketElementorPreload.run)})();</script></body>
</html>
				
			

Copy and modify for second site:

				
					cp /var/www/example.com/public_html/index.html /var/www/testsite.org/public_html/index.html
nano /var/www/testsite.org/public_html/index.html
				
			

Change title and heading to testsite.org.

Step 4: Create Virtual Host Config Files

Copy the default config as a template:

				
					sudo cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/example.com.conf
sudo cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/testsite.org.conf
				
			

Edit first site:

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

Update to:

				
					<VirtualHost *:80>
    ServerAdmin webmaster@example.com
    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>
				
			

Repeat for second site (testsite.org.conf), changing names, aliases, and DocumentRoot.

Step 5: Enable Virtual Hosts & Disable Default

Enable sites:

				
					sudo a2ensite example.com.conf
sudo a2ensite testsite.org.conf
				
			

Disable default site:

				
					sudo a2dissite 000-default.conf
				
			

Test config:

				
					sudo apache2ctl configtest
				
			

Should return Syntax OK.

Reload Apache:

				
					sudo systemctl reload apache2
				
			

Step 6: (Optional) Test Locally Without Real DNS

On your local computer (not server), edit hosts file:

Linux/macOS:

				
					sudo nano /etc/hosts
				
			

Windows (admin Notepad):

				
					C:\Windows\System32\drivers\etc\hosts
				
			

Add:

				
					your_server_ip   example.com
your_server_ip   www.example.com
your_server_ip   testsite.org
your_server_ip   www.testsite.org
				
			

Save → open browser → visit http://example.com and http://testsite.org — you should see the correct pages.

Step 7: Verify & Go Live

  • Visit domains in browser (or local hosts test)
  • Check logs if issues: tail -f /var/log/apache2/example.com_error.log
  • For production: Add HTTPS with Let’s Encrypt (certbot –apache)

How to Set Up Apache Virtual Hosts on Ubuntu – FAQ (2025–2026)

  1. How do I set up Apache virtual hosts on Ubuntu for multiple domains? 
    Create /var/www/domain/public_html, config in /etc/apache2/sites-available/domain.conf, enable with a2ensite, reload Apache.
  2. Where are virtual host files stored when setting up Apache virtual hosts on Ubuntu?
    /etc/apache2/sites-available/ — enable with a2ensite, symlinks go to sites-enabled/.
  3. How do I test virtual hosts locally when setting up Apache virtual hosts on Ubuntu?
    Edit your computer’s /etc/hosts file to point domains to server IP — no DNS needed.
  4. What is ServerName vs ServerAlias when setting up Apache virtual hosts on Ubuntu?
    ServerName = primary domain; ServerAlias = additional names (www, subdomains).
  5. How do I disable the default site when setting up Apache virtual hosts on Ubuntu?
    sudo a2dissite 000-default.conf → reload Apache.

Conclusion

You now have a single server handling two separate domain names. You can expand this process by following the steps we outlined above to add additional virtual hosts. There is no software limit on the number of domain names Apache can handle, so feel free to make as many virtual hosts as your server is capable of handling.

Now that you’ve mastered how to set up Apache virtual hosts on Ubuntu, you’re ready to host multiple production websites efficiently on the same server while maintaining clean separation and optimal performance.

Next steps: Add HTTPS (Let’s Encrypt), optimise performance, secure with .htaccess, or automate with Ansible.

Recommended Resources

  • Official Apache Virtual Host Docs
  • Let’s Encrypt + Certbot on Ubuntu
  • Apache Performance Tuning Guide
  • UFW Firewall Setup for Web Servers