How to Setup Apache Virtual Hosts on Ubuntu 20.04 (Step by Step)

How to Setup Apache Virtual Hosts on Ubuntu 20.04 (Step by Step). Apache is one of the best web servers that accounts for more than 50% of all active websites and applications on the internet. It is a tool that aims at delivering content on the web without hassle.

 

Apache web server breaks its components and functionality into units that can be configured and customized independently. One of these units is the Apache Virtual Host; a component used to describe a domain or a website.

Apache Virtual Hosting

Virtual Hosting is an Apache feature that allows users to host more than one website on a single server (physical server or cloud based server). The best thing about this virtual host is that it enables the users to use any virtual host within a single server. It maps out requests of every domain into a document root respectively, where all the files of the sites are located. Generally, Virtual Hosting features are used in Shared web hosting and Reseller web hosting.

There are two main types of virtual hosting, name based hosting and IP based. Each virtual host has its own unique IP address and name based virtual hosts.

1. Name Based Virtual Hosting

Name based virtual hosting uses different domain names controller to host multiple websites on a single server with a single IP address. In name based virtual hosting, all domains will share a single IP. So you will need to map all domains with a single IP via the DNS control panel. Mostly, users rely on the name based virtual host as they find it a lot more convenient than an IP based Virtual Host.

IP Based Virtual Hosting

IP based virtual hosting uses multiple IP addresses to host multiple websites on a single server. You will require multiple NICs (Network Interface Card) and assign different IPs to each NIC. This way you can define different directives based on the IP address a request is received on.

Lab Environment

Operating System – Ubuntu 20.04
Application – Apache Web Server
IP Address – 192.168.0.10
IP Address – 192.168.0.11
Domain – web1.example.com
Domain – web2.example.com

Note: Both domains must be pointed with your server’s IP address.

Follow this post to learn how to setup Apache Virtual Hosts on Ubuntu 20.04.

How to Setup Apache Virtual Hosts on Ubuntu 20.04

Install Apache Web Server

Before starting, you will need to install the Apache web server on your server. You can install it by running the following command:

				
					apt-get install apache2 -y
				
			

Once the Apache web server is installed, start and enable the Apache service with the following command:

				
					systemctl start apache2
systemctl enable apache2

				
			

Now, open your web browser and verify the Apache web server using the URL http://your-server-ip. You should see the Apache test page:

Create Apache Directory Structure

For testing name based virtual hosting and IP based virtual hosting, you will need to create a directory structure for all websites.

First, create a directory for both domain inside the Apache web root using the following command:

				
					mkdir /var/www/html/web1.example.com /var/www/html/web2.example.com
				
			

Next, create an empty index.html file for both domain:

				
					touch /var/www/html/web1.example.com/index.html
touch /var/www/html/web2.example.com/index.html

				
			

Create a directory for both IP with the following command:

				
					mkdir /var/www/html/ip1 /var/www/html/ip2
				
			

Then create an empty index.html file for both IPs:

				
					touch /var/www/html/ip1/index.html
touch /var/www/html/ip2/index.html
				
			

Now, verify your directory structure using the following command:

				
					tree /var/www/html/
				
			

You will get the following output:

				
					/var/www/html/
├── index.html
├── ip1
│   └── index.html
├── ip2
│   └── index.html
├── web1.example.com
│   └── index.html
└── web2.example.com
    └── index.html

				
			

Create Web Pages for Each Website

Here we will need to create an index.html web page inside the web root directory of each website that will be shown when you visit the domain in your browser.

First, create an index.html page for web1.example.com domain:

				
					nano /var/www/html/web1.example.com/index.html
				
			

Add the following code:

				
					<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    
    <p>Welcome to web1.example.com</p>
  </head>
  <body>
    <p>Success! web1.example.com home page!</p>
  <script>class RocketElementorAnimation{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)}_detectAnimations(){let t=getComputedStyle(this.deviceMode,":after").content.replace(/"/g,"");this.animationSettingKeys=this._listAnimationSettingsKeys(t),document.querySelectorAll(".elementor-invisible[data-settings]").forEach(t=>{const e=t.getBoundingClientRect();if(e.bottom>=0&&e.top<=window.innerHeight)try{this._animateElement(t)}catch(t){}})}_animateElement(t){const e=JSON.parse(t.dataset.settings),i=e._animation_delay||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 s=setTimeout(()=>{t.classList.remove("elementor-invisible"),t.classList.add("animated",n),this._removeAnimationSettings(t,e)},i);window.addEventListener("rocket-startLoading",function(){clearTimeout(s)})}_listAnimationSettingsKeys(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}_removeAnimationSettings(t,e){this._listAnimationSettingsKeys().forEach(t=>delete e[t]),t.dataset.settings=JSON.stringify(e)}static run(){const t=new RocketElementorAnimation;requestAnimationFrame(t._detectAnimations.bind(t))}}document.addEventListener("DOMContentLoaded",RocketElementorAnimation.run);</script></body>
</html>

				
			

Save and close the file then create an index.html page for web2.example.com domain:

				
					nano /var/www/html/web2.example.com/index.html
				
			

Add the following code:

				
					<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    
    <p>Welcome to web2.example.com</p>
  </head>
  <body>
    <p>Success! web2.example.com home page!</p>
  </body>
</html>

				
			

Save and close the file then create an index.html page for ip1:

				
					nano /var/www/html/ip1/index.html
				
			

Add the following code:

				
					<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    
    <p>Welcome to 192.168.0.10</p>
  </head>
  <body>
    <p>Success! 192.168.0.10 home page!</p>
  </body>
</html>

				
			

Save and close the file then create an index.html page for ip2:

				
					nano /var/www/html/ip2/index.html
				
			

Add the following code:

				
					<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    
    <p>Welcome to 192.168.0.11</p>
  </head>
  <body>
    <p>Success! 192.168.0.11 home page!</p>
  </body>
</html>

				
			

Save and close the file then change the ownership of the Apache web root:

				
					chown -R www-data:www-data /var/www/html
				
			

Configure Apache Virtual Hosts

By default, Apache Virtual Hosts configuration files are located in /etc/apache2/sites-available directory on Ubuntu 20.04. In this section, we will create an Apache virtual host configuration file for both name based and ip based virtual hosting.

Configure Name Based Virtual Hosts

Name based virtual hosting allows you to host multiple websites on a single server using domain name.  First, create an Apache virtual host for web1.example.com domain:

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

Add the following lines:

				
					<VirtualHost *:80>
    ServerName web1.example.com
    ServerAdmin webmaster@web1.example.com
    DocumentRoot /var/www/html/web1.example.com

    <Directory /var/www/html/web1.example.com>
        Options -Indexes +FollowSymLinks
        AllowOverride All
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/web1.example.com-error.log
    CustomLog ${APACHE_LOG_DIR}/web1.example.com-access.log combined
</VirtualHost>

				
			

Save and close the file when you are finished. Next, create an Apache virtual host for web2.example.com domain:

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

Add the following lines:

				
					<VirtualHost *:80>
    ServerName web2.example.com
    ServerAdmin webmaster@web2.example.com
    DocumentRoot /var/www/html/web2.example.com

    <Directory /var/www/html/web2.example.com>
        Options -Indexes +FollowSymLinks
        AllowOverride All
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/web2.example.com-error.log
    CustomLog ${APACHE_LOG_DIR}/web2.example.com-access.log combined
</VirtualHost>
				
			

Save and close the file then activate both virtual host configuration files using the following command:

				
					ln -s /etc/apache2/sites-available/web1.example.com.conf /etc/apache2/sites-enabled/
ln -s /etc/apache2/sites-available/web2.example.com.conf /etc/apache2/sites-enabled/

				
			

Next, verify the Apache configuration file using the following command:

				
					apachectl configtest 
				
			

You should get the following output:

				
					Syntax OK
				
			

Finally, restart the Apache service to apply the changes:

				
					systemctl restart apache2
				
			

Configure IP Based Virtual Hosts

IP based virtual hosting allows you to host multiple websites on a same server by using assigning a separate IP for each website. First, create an Apache virtual host configuration file for IP 192.168.0.10:

				
					nano /etc/apache2/sites-available/ip1.conf
				
			

Add the following lines:

				
					<VirtualHost 192.168.0.10:80>
    ServerName 192.168.0.10
    ServerAdmin webmaster@192.168.0.10
    DocumentRoot /var/www/html/ip1

    <Directory /var/www/html/ip1>
        Options -Indexes +FollowSymLinks
        AllowOverride All
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/192.168.0.10-error.log
    CustomLog ${APACHE_LOG_DIR}/192.168.0.10-access.log combined
</VirtualHost>
				
			

Save and close the file when you are finished. Next, create an Apache virtual host configuration file for IP 192.168.0.11:

				
					nano /etc/apache2/sites-available/ip2.conf
				
			

Add the following lines:

				
					<VirtualHost 192.168.0.11:80>
    ServerName 192.168.0.11
    ServerAdmin webmaster@192.168.0.11
    DocumentRoot /var/www/html/ip2

    <Directory /var/www/html/ip2>
        Options -Indexes +FollowSymLinks
        AllowOverride All
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/192.168.0.11-error.log
    CustomLog ${APACHE_LOG_DIR}/192.168.0.11-access.log combined
</VirtualHost>
				
			

Save and clsoe the file then activate both virtual host configuration files using the following command:

				
					ln -s /etc/apache2/sites-available/ip1.conf /etc/apache2/sites-enabled/
ln -s /etc/apache2/sites-available/ip2.conf /etc/apache2/sites-enabled/
				
			

Next, verify the Apache configuration file using the following command:

				
					apachectl configtest 
				
			

You should get the following output:

				
					Syntax OK
				
			

Finally, restart the Apache service to apply the changes:

				
					systemctl restart apache2
				
			

You can also check the Apache running status using the following command:

				
					systemctl status apache2
				
			

You will get the following output:

				
					● apache2.service - The Apache HTTP Server
   Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor preset: enabled)
  Drop-In: /lib/systemd/system/apache2.service.d
           └─apache2-systemd.conf
   Active: active (running) since Fri 2022-05-06 10:28:54 IST; 3s ago
  Process: 8037 ExecStop=/usr/sbin/apachectl stop (code=exited, status=0/SUCCESS)
  Process: 7111 ExecReload=/usr/sbin/apachectl graceful (code=exited, status=0/SUCCESS)
  Process: 8042 ExecStart=/usr/sbin/apachectl start (code=exited, status=0/SUCCESS)
 Main PID: 8046 (apache2)
    Tasks: 55 (limit: 4915)
   CGroup: /system.slice/apache2.service
           ├─8046 /usr/sbin/apache2 -k start
           ├─8047 /usr/sbin/apache2 -k start
           └─8048 /usr/sbin/apache2 -k start

May 06 10:28:54 vyompc systemd[1]: Stopped The Apache HTTP Server.
May 06 10:28:54 vyompc systemd[1]: Starting The Apache HTTP Server...
May 06 10:28:54 vyompc systemd[1]: Started The Apache HTTP Server.
				
			

Verify Name Based and IP Based Virtual Hosting

At this point, name based and IP based virtual hosting are configured on Ubuntu 20.04 server. Now, it’s time to verify that everything is working as expected.

Open your web browser and access both domain by their name using the URL:

http://web1.example.com

You should see the content of the index.html hosted on the web1.example.com domain in the following page:

http://web2.example.com

You should see the content of the index.html hosted on the web2.example.com domain in the following page:

You can also access both website by their IPs using the URL:

http://192.168.0.10

You should see the content of the index.html hosted on the IP 192.168.0.10 in the following page:

http://192.168.0.11

You should see the content of the index.html hosted on the IP 192.168.0.11 in the following page:

How to Setup Apache Virtual Hosts on Ubuntu 20.04 Conclusion

In this guide, we explained how to setup apache virtual hosts on Ubuntu 20.04. We also setup both name based and IP based virtual hosting by real life examples. I hope you can now easily host multiple websites on a single server using the Apache virtual hosting feature.

Avatar for Hitesh Jethva
Hitesh Jethva

I am a fan of open source technology and have more than 10 years of experience working with Linux and Open Source technologies. I am one of the Linux technical writers for Cloud Infrastructure Services.

0 0 votes
Article Rating
Subscribe
Notify of
0 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x