How to Host Multiple Websites with Apache Virtual Hosts
By: Shinichi Okada
Tags: Servers, Hosting, Websites, Apache, Virtual Host

How to Host Multiple Websites with Apache Virtual Hosts

Introduction

Apache’s virtual hosts can run multiple websites on a single server. In this article, you will learn how to host multiple websites including sub-domains.

My Ubuntu 20.04 server has some files in the /etc/apache2/sites-available directory. We will create more files in this directory to create multiple virtual hosts.

$ ls /etc/apache2/sites-available

000-default.conf 000-default-le-ssl.conf default-ssl.conf

000-default.conf.dpkg-dist

Creating a new virtual host

Let’s create a virtual host for example.com . (You need to change example.com to your domain name.) We store files in the /var/www/example.com/public_html directory. If you want to deploy your website using Git, please refer to this article “How to Create a Git Hook to Push to Your Server and Github Repo”.

Step 1 — Create a conf file

Copy 000-default.com.conf to create a new file in /etc/apache2/sites-available :

$ cd /etc/apache2/sites-available

$ sudo cp 000-default.com.conf example.com.conf

Step 2 — Modify the new conf file

In the example.com.conf :

Line 2: Add your email for ServerAdmin

Line 3: Use your domain name for ServerName.

Line 4: Add www to your domain name for ServerAlias.

Line 5 & 6: Add the file directory for DocumentRoot.

Step 3 — Enabling a virtual host

a2ensite enables the specified site within the apache2 configuration. It creates a symlink within /etc/apache2/sites-enabled (not sites-available).

$ sudo a2ensite example.com.conf

The above command will create a symlink, example.com.conf , within the /etc/apache2/sites-enabled directory.

Step 4— Enabling SSL

$ sudo certbot --apache -d example.com -d www.example.com

This will look in /etc/apache2/sites-available to find the same file name. If it can’t find it, it will ask you to select the conf file.

This will create example.com-le-ssh.conf .

Step 5— Restart apache

$ sudo systemctl restart apache2

If your DNS is configured correctly, you should be able to see your domain.

Subdomains

We are going to create a virtual host for a subdomain. The process is the same as in the previous section.

We store web files within /var/www/newsletter.example.com/public_html .

We copy 000-default.com.conf to create a new file newsletter.example.com.conf .

$ sudo cp 000-default.com.conf newsletter.example.com.conf

Edit the newsletter.example.com.conf :

The differences from the previous one are adding a subdomain to the ServerName, ServerAlias, DocumentRoot, and Directory.

Enabling a virtual host and SSL

Let’s enable a virtual host and SSL for this subdomain.

sudo a2ensite newsletter.example.com.conf

sudo certbot --apache -d newsletter.example.com -d www.newsletter.example.com

Adding A record to your DNS service

If you are using namecheap.com, go to Domain List > Advanced DNS and add a new record.

It may take 24–48 hours.

Restarting apache

$ sudo systemctl restart apache2

Confirm you DNS

Check your DNS using https://www.whatsmydns.net/. If you configured it correctly, it shows your IP address.

etc/apache2/sites-available

Now you have the following files within the sites-available directory.

ls /etc/apache2/sites-available/

000-default.conf 000-default.conf.dpkg-dist

default-ssl.conf 000-default-le-ssl.conf

example.com.conf example.com-le-ssl.conf

newsletter.example.com.conf newsletter.example.com-le-ssl.conf

xxxx-le-ssl.conf files are for your SSL.

How to remove a virtual host

Use the a2dissite command to disable the existing virtual hosts.

$ sudo a2dissite 000-default.conf

$ sudo a2dissite 000-default-le-ssl.conf

Here you are disabling 000-default.conf and its SSL virtual hosts.

Conclusion

Now you know how to create virtual hosts on your server. This allows you to host as many websites as you like on one server.

If you like my article and would like to receive newsletters, please sign up.

Get full access to every story on Medium by becoming a member.

References