The virtual hosting concept is used by companies to host multiple websites using a single machine. It can be achieved either by an ‘IP-based’ method or a ‘name-based’ approach. In ‘IP-based’ hosting we have distinct IP addresses for each website. In the case of ‘name-based’ hosting, we have multiple names running on each IP address.

What will we cover?

In this tutorial, we will see how we can host two virtual hosts on an Ubuntu 22.04 system using name-based virtual hosting. We will use the Apache web server.

Get started now… 

Step 1. Update the repository and the operating system as well:

sudo apt update
sudo apt upgrade -y

Step 2. Install Apache web server for Ubuntu using the command:

sudo apt install apache2 -y

<img alt="Installing Apache" data-ezsrc="" ezimgfmt="rs rscb5 src ng ngcb5" height="410" loading="lazy" src="data:image/svg xml,” width=”750″>

Step 3. Restart the Apache web server and check its status by running:

sudo systemctl restart apache2
sudo systemctl status apache2

<img alt="Restarting Apache service" data-ezsrc="" ezimgfmt="rs rscb5 src ng ngcb5" height="304" loading="lazy" src="data:image/svg xml,” width=”750″>

Sample Output:

? apache2.service - The Apache HTTP Server

     Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor prese>

     Active: active (running) since Mon 2022-06-27 09:32:14 UTC; 18s ago


    Process: 13093 ExecStart=/usr/sbin/apachectl start (code=exited, status=0/S>

   Main PID: 13098 (apache2)

      Tasks: 55 (limit: 1146)

     Memory: 4.7M

        CPU: 25ms

     CGroup: /system.slice/apache2.service

             ??13098 /usr/sbin/apache2 -k start

             ??13099 /usr/sbin/apache2 -k start

             ??13100 /usr/sbin/apache2 -k start

Step 4. Create two new directories inside the ‘www’ folder. Let these directories be host1 and host2. 

Again, inside these directories create one more folder to hold your web files.  Let these directories be public_html and public_html. These directories will contain the corresponding index.html files for these two hosts:

sudo mkdir -p /var/www/host1/public_html
sudo mkdir -p /var/www/host2/public_html

The directories ‘/var/www/host1/public_html’ and ‘/var/www/host2/public_html’ also represent the document root for the two virtual hosts.

Step 5. The directories created above are owned by the root user. To let a regular user modify the files in these directories, the ownership should be changed using the commands:

sudo chown -R $USER:$USER /var/www/host1/public_html
sudo chown -R $USER:$USER /var/www/host2/public_html

The ‘$USER’ variable will use the value of the current logged in user. The ‘public_html’ will now be owned by this user.

Step 6. Now set ‘read access’ permission for the apache general web directory:

sudo chmod -R 755 /var/www

Step 7. Now we will set a default page i.e. index.html for each virtual host. This can be done directly from the terminal using the ‘echo’ command. For virtual host1:

sudo echo “Welcome to Virtual Host 1.” > /var/www/host1/public_html/index.html

For virtual host2:

sudo echo “Welcome to Virtual Host 2.” > /var/www/host2/public_html/index.html

Step 8. Before proceeding further, we are using an intermediary step. Here we will modify the hosts file to map the local host address to the two virtual host domain names: and This is done to avoid publicly registering our domain names.

sudo sh -c "echo >> /etc/hosts"
sudo sh -c "echo >> /etc/hosts"

The above steps are shown in the picture below:

<img alt="Preparing the virtual hosts" data-ezsrc="" ezimgfmt="rs rscb5 src ng ngcb5" height="203" loading="lazy" src="data:image/svg xml,” width=”750″>

Step 9. We will now create two Virtual host files for each of our virtual hosts. These are similar two the apache default config file(“000-default.conf”). Now these files will represent the configuration to be used for our virtual hosts and also govern how the various domain requests are responded to by an Apache web server.

The “000-default.conf” can be used as a base file for each virtual host. Simply copy this file to the same location with two different names: host1.conf and host2.conf:

sudo cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/host1.conf
sudo cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/host2.conf

Step 10. Now open the files and modify them for each virtual host. For e.g., for virtual host1, the following parameters should be modified as:

    ServerAdmin [email protected]

    ServerName host1


    DocumentRoot /var/www/host1/public_html

    ErrorLog ${APACHE_LOG_DIR}/error.log

For the second file(host2.conf), replace the host1 entries with the host2. Alternatively, you can create two new files and enter the above content corresponding to each virtual host. The file host2.conf will look like:

    ServerAdmin [email protected]

    ServerName host2


    DocumentRoot /var/www/host2/public_html

    ErrorLog ${APACHE_LOG_DIR}/error.log

Step 10. Now that we have created the virtual host files, it’s time to actually enable these files. For this purpose, Apache provides a tool called ‘a2ensite’. Use the command below to enable them:

sudo a2ensite host1.conf
sudo a2ensite host2.conf

Step 11. On the terminal, you will see a message to reload apache to activate the new configuration, but before that disable the default site represented by “000-default.conf” using the command:

sudo a2dissite 000-default.conf

Step 12. Check the config files for any syntax error using:

sudo apache2ctl configtest

Step 13. Finally, reload the apache2 service to apply the changes made above:

sudo systemctl reload apache2

<img alt="(1) Enable Host1 and Host2 (2) Disable the default site (3) Reload Apache" data-ezsrc="" ezimgfmt="rs rscb5 src ng ngcb5" height="351" loading="lazy" src="data:image/svg xml,” width=”750″>

Testing the Apache vhost Setup

We will now check if everything is setup correctly. Open a terminal on your machine and run the command:

$ curl

The above command should return the message from the virtual host1 index page, similarly, the below command should display the message from the virtual host2:

$ curl

<img alt="Testing the Setup" data-ezsrc="" ezimgfmt="rs rscb5 src ng ngcb5" height="183" loading="lazy" src="data:image/svg xml,” width=”750″>


We have finally made it out, our virtual hosting is working as expected. We can also perform this tutorial using Terraform, just try it out.