LowEndBox - Cheap VPS, Hosting and Dedicated Server Deals

How To Set Up Apache Virtual Hosts on CentOS 7

In this tutorial, we will start with an empty VPS with a freshly installed CentOS 7 and will end up with three different sites sharing the same IP address, hosted on the same machine.

Apache web server analyzes HTTP request headers and appropriately connects it to the directory structure inside the VPS. The technical term for “sites” inside VPS boxes is “virtual host” – the server is the “host” to many domains at the same time, hence, they are not real, but only “virtual”.

Let’s see how it’s done.

What We Are Going To Cover

  • Creating a Non Root User
  • Installing Apache
  • Installing and setting up firewall
  • Defining File Locations For the Default Apache Page
  • Creating File Structure For Our Demo Virtual Hosts
  • Granting Permissions
  • Creating index.html Pages For Our Demo Sites
  • Creating Virtual Hosts Files
  • Turning On the New Virtual Host Files
  • Testing the Virtual Hosts
  • Securing Your Domains With Let’s Encrypt TLS certificates


We’ll use CentOS 7:

  • Starting with a clean VPS with
  • At least 512Mb of RAM and
  • 15Gb of free disk space
  • You will need root user access via SSH
  • Two domain names pointed to your server’s IP address using A records at your DNS service provider.
  • We use nano as our editor of choice, and you can install it with this command:
sudo yum install nano -y

Step 1: Update the System

First, update your system to the latest stable version by running the following command:

sudo yum update -y
sudo reboot

It may take several minutes for the transaction to get finished. You can always stop it by pressing Ctrl-C, but Centos will later, while performing another transaction, ask you to finish this transaction first. Be patient.

Step 2: Create User With Non-root Privileges

Sudo is already installed on Centos. Add user simpleuser and make it have access to the sudo command:

adduser simpleuser

Debian and Ubuntu will automatically ask you for the new user’s password but on Centos you have to do it yourself:

passwd simpleuser

Add simpleuser to the wheel group:

usermod -aG wheel simpleuser

Step 3: Clean Up yum Cache

When installing packages, yum will download them into its special cache. After successful installation, the packages should be deleted from the cache, but it may not always be the case. The following command will clean all cached information:

sudo yum clean all

It will also reclaim disk space or clear errors due to corrupted metadata files.

This is a typical result:

Step 4: Install Apache

Apache installation files are in the yum repository, so one command is more than enough to install it:

sudo yum -y install httpd

Step 5: Install firewalld as Our Firewall

Apache uses standard ports 80 and 443 for HTTP and HTTPS traffic, respectively.

Let’s now install firewall-cmd, the command line front-end for firewalld (firewalld daemon), for CentOS. It supports both IPv4 and IPv6, firewall zones, bridges and ipsets, allows for timed firewall rules in zones, logs denied packets, automatically loads kernel modules, and so on.

Install it in the usual manner, by using yum:

yum install firewalld

Let us now start it, enable it to auto-start at system boot, and see its status:

systemctl start firewalld
systemctl enable firewalld
systemctl status firewalld

Firewall is now running:

Here is a list of ports and feel free to add any other that your host requires for the normal functioning of the system:

firewall-cmd --permanent --zone=public --add-service=ssh
firewall-cmd --zone=public --add-port=3000/tcp --permanent
firewall-cmd --zone=public --add-port=8080/tcp --permanent
firewall-cmd --permanent --zone=public --add-service=http
firewall-cmd --permanent --zone=public --add-service=https
firewall-cmd --reload

We have added addresses 3000 and 8080 as examples only and will not use them in the rest of this text. You should, however, do well to find out the list of ports that the applications on your VPS are going to need and put them in this exact spot for later.

Always enable ssh, http, https and other critical ports in ufw, otherwise you will NOT be able to log back into your VPS server, nor see you site!

Now we can start Apache:

sudo systemctl start httpd

We want Apache to always be there so we make sure that it starts at boot:

sudo systemctl enable httpd

We can check the status of Apache:

sudo systemctl status httpd

This would be a typical output for the status of Apache:

The following command, to stop Apache from running, is here for your reference only (do not execute it as a part of this installation)

sudo systemctl stop httpd

The real test of successful installation is whether you can access files from the server through your local browser. Navigate to this address:


You should see a welcome page for Apache on CentOS, which means that you now have Apache running on your VPS.

Step 6: Configure SELinux

You’ll also need to configure SELinux (a security system within Centos) to allow Apache to operate normally:

sudo setsebool -P httpd_unified 1

Step 7: File Locations For the Default Apache Page

In CentOS, root document directory is in directory /var/www/html and if it contains file index.html, its contentw will be shown to the world. The fresh installation of Centos does NOT contain one such file in that directory and is set up so that in that case, it will show the contents of file


That’s the page with grey background and with Testing 1 2 3 as the headline that we have already seen.

Let us now install an index.html page into proper document root i.e. /var/www/html. Create that file by opening it in nano:

sudo nano /var/www/html/index.html

and insert the following text:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
<title>Untitled Document</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css">
.style1 {color: #66CC66}

<h1><span class="style1">Centos 7 Root document index.html file 

Enter the address of the site into the browser address line and get this:

The directories and the index.html files belong to the root user.

Under CentOS 7, all Apache files are stored in folder /etc/httpd:

ls -la /etc/httpd

We shall now create directories sites-available and sites-enabled which will hold information on sites that exist and on sites that are permitted to be served to the Internet, respectively:

sudo mkdir /etc/httpd/sites-available /etc/httpd/sites-enabled

You’ll also need to configure Apache to look for them by adding a line of configuration. Open the main config file:

sudo nano /etc/httpd/conf/httpd.conf

Scroll down to the very end of the file and add the following line:

IncludeOptional sites-enabled/*.conf

Save and close the file.

This is what you should see:

By adding more config files into /etc/httpd/sites-available and creating the corresponding symbolic links in /etc/httpd/sites-enabled, we can serve different pages to different domains. That is how we can host multiple independent sites off of one and the same IP address.

Each site in Apache parlance is called “virtual host” and will have to reside in its own subdirectory. The plan for adding new virtual hosts boils down to

  • creating file structure for each site,
  • populating HTML and other files in the site,
  • creating a new .conf file in /etc/httpd/sites-available, and
  • creating a new symbolic link in /etc/httpd/sites-enabled.

Apache will then do the rest, automatically.

Step 8: Creating File Structure For Our Demo Virtual Hosts

We will create two virtual hosts called centos1.com and centos2.com. They will correspond to DNS entries centos1.duskosavic.com and centos2.duskosavic.com that we have previously made using A records at our DNS service provider. (Instead of these, you should enter your own site domains.) If we now navigated to http://centos1.duskosavic.com/_ in a browser, the default index.html page with basic Apache information would be served, again.

Let’s now create a directory to hold our centos1.com site. Apache on Ubuntu stores its HTML files under /var/www/html so we could also use it to create our demo sites there. One possibility is to make that folder the top one and to put the demo sites into it. With commands such as

cd /var/www/html
sudo mkdir centos1.com
sudo mkdir centos2.com
ls -la

we would have the following directory structure:

Here we decide upon the other possibility, and that is to go one level up the directory tree and create the demo sites in /var/www. Inside folders centos1.com and centos2.com we can create whatever directory structure we need, for example:

cd /var/www
sudo mkdir -p /var/www/centos1.com/{public_html,private,log,cgi-bin,backup}
sudo mkdir -p /var/www/centos2.com/{public_html,private,log,cgi-bin,backup}
ls /var/www/centos1.com -la

Step 9: Granting Permissions

From the image above we see that root user is still owning the public_html folder, from which our public files will be served to the Internet. We will now change the ownership so that our simpleuser can access the public_html files. The commands are:

sudo chown -vR apache:apache /var/www/centos1.com/public_html
sudo chown -vR apache:apache /var/www/centos2.com/public_html

Also make sure that files in /var/www and its subfolders can be read correctly:

sudo chmod -R 755 /var/www

Step 10: Create index.html Pages For Our Demo Sites

Our public files will be in /var/www/centos1.com/public_html and /var/www/centos2.com/public_html. We’ll now create an index.html in each of these two folders so that we have something to see while browsing. Using nano, we will create index.html for centos1.com:

sudo nano /var/www/centos1.com/public_html/index.html

We need only one line of text, preferably in H1 format for better readability. Insert the following text into nano, then save and close the file:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
<title>centos1.com Title</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css">
body,td,th {
    color: #FF3333;

<h1>This is centos1.com 

Create index.html for centos2.com:

sudo nano /var/www/centos2.com/public_html/index.html

and paste this in:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
<title>centos2.com Title</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css">
.style1 {color: #3333FF}

<h1 class="style1">This is centos2.com</h1>

Step 11: Create Virtual Hosts Files

We’ll now inform Apache that there are two new sites to be served by creating two new Virtual Hosts.

Step 11A: Create the First Virtual Hosts File

Create the first virtual host file:

sudo nano /etc/httpd/sites-available/centos1.com.conf

Paste in the following (and change the domain names to yours):

<VirtualHost *:80>
    ServerAdmin admin@centos1.com
    ServerName centos1.com
    ServerAlias centos1.duskosavic.com
    ServerAlias www.centos1.com
    DocumentRoot /var/www/centos1.com/public_html
    #ErrorLog ${APACHE_LOG_DIR}/error.log
    #CustomLog ${APACHE_LOG_DIR}/access.log combined

Here is a detailed explanation of the above virtual host:

  • 80: This virtual host will listen on port 80. You can change port number through file httpd.conf with this command:
sudo nano /etc/httpd/conf/httpd.conf

You’ll find a Listen directive with port 80 specified, and that is where you can customize it. Remember to restart Apache afterwards by running:

sudo systemctl restart httpd
  • ServerAdmin: It is the email address to which Apache will send messages for administrator in case of an error in the system. May be omitted.
  • ServerName: Server name, obviously, it should coincide with the domain name.
  • ServerAlias: Another name for the same server as above. You can have as many of these aliases as you like.
  • DocumentRoot: Points to the absolute address of the site on disk.

Step 11B: Create the Second Virtual Hosts File

Do the same for the other site/domain. Here are the commands:

sudo nano /etc/httpd/sites-available/centos2.com.conf

This is what you should return paste into nano:

<VirtualHost *:80>
    ServerAdmin admin@centos2.com
    ServerName centos2.duskosavic.com
    ServerAlias www.centos2.com
    DocumentRoot /var/www/centos2.com/public_html
#    ErrorLog ${APACHE_LOG_DIR}/error.log
#    CustomLog ${APACHE_LOG_DIR}/access.log combined

Save and close the file.

Step 12: Turn On the New Virtual Host Files

You’ll have to create symbolic links from sites-enabled directory to sites-available, so Apache will start serving the virtual hosts. The commands are:

sudo ln -s /etc/httpd/sites-available/centos1.com.conf /etc/httpd/sites-enabled/centos1.com.conf
sudo ln -s /etc/httpd/sites-available/centos2.com.conf /etc/httpd/sites-enabled/centos2.com.conf

If you want to disable the default site, the command would be:

sudo mv /etc/httpd/conf.d/welcome.conf /etc/httpd/conf.d/welcome.conf.bak

Then, restart Apache:

sudo systemctl restart httpd

Be sure to clear cache in your browser or it may start fooling you with old values instead of the properly refreshed ones.

Step 13: Testing the Virtual Hosts

If you have left the default IP address activated, it will currently show the ‘Welcome to Apache’ screen. If you enter the address centos1.duskosavic.com, you will see this:

And entering centos2.duskosavic.com into the browser changes the image to:

Step 14: Securing Your Domains With Let’s Encrypt SSL

We can use free TLS certificates from Let’s Encrypt to turn our HTTP traffic into HTTPS traffic, which will make connecting to your site secure.

Certbot for CentOS 7 comes from the EPEL repository, which you’ll need to install first:

sudo yum install epel-release -y

Install Certbot:

sudo yum install certbot python2-certbot-apache -y

Then, run Certbot:

sudo certbot --apache

It will ask for your email address in case of emergency, then another two questions that you may answer however you like and then the most important question – which names would you like to activate HTTPS for?

Choose your domain(s) from the list.

The last question will be whether do you want HTTPS access or not. You do, so choose 2.

Restart Apache:

sudo systemctl restart httpd

In your browser, go to address


We have entered the HTTP address and Apache automatically redirects to HTTPS, as it should:

You’ll notice that the actual site address starts with HTTPS and that there is green padlock in the address bar, signifying a secure connection.

Let’s Encrypt certificates expire after 90 days. Certbot can automatically renew them for you, but it must be told to do so:

echo "0 0,12 * * * root python -c 'import random; import time; time.sleep(random.random() * 3600)' && certbot renew" | sudo tee -a /etc/crontab > /dev/null

What Can You Do Next

We have shown how to share one IP address to one, two, three or dozens or hundreds of independent sites. You can now use this knowledge to host all your sites on one low cost VPS box, running CentOS 7.

Dusko Savic is a technical writer and programmer.


Kaylee Westover

No Comments

    Leave a Reply

    Some notes on commenting on LowEndBox:

    • Do not use LowEndBox for support issues. Go to your hosting provider and issue a ticket there. Coming here saying "my VPS is down, what do I do?!" will only have your comments removed.
    • Akismet is used for spam detection. Some comments may be held temporarily for manual approval.
    • Use <pre>...</pre> to quote the output from your terminal/console, or consider using a pastebin service.

    Your email address will not be published. Required fields are marked *