Apache2 VirtualHosts
In this tutorial, we use VirtualHosts so that our server may support multiple domain names.
We do this by configuring Apache2 to recognize new DocumentRoot directories for the additional domain names.
This allows us to serve multiple websites based on the same IP address.
Update OS
As always, we need to keep our Fedora installation updated:
dnf upgrade
Create new configurations
So far we have learned how to create a main website at the following document root:
/var/www/html
We have also learned how to enable Apache2 to serve websites from user directories:
/home/USER/public_html/.
Websites that are stored at /var/www/html can eventually have a
domain name like example.org or biguniversity.edu. And then
websites at /home/USER/public_html/ would have URLs like
http://biguniversity.edu/~USER
.
The problem with creating a website at the /var/www/html DocumentRoot is that, by default, we can only create the one main site; so either example.org or biguniversity.edu but not both.
VirtualHosts solve this problem. It allows a single server, with a single IP address, to host websites linked to multiple domain names, where all of these sites would have their own DocumentRoot directories in the /var/www/html directory.
To start, we need to revisit the Apache configuration files and add information about the VirtualHosts that we want to create.
We begin by adding VirtualHost information to the following file:
less /etc/httpd/conf/httpd.conf
That file includes the following line:
IncludeOptional conf.d/*.conf
That option tells the Apache2 service to look for additional configuration files in the conf.d/ directory. Per that above line, the configuration files that we add will need to end with .conf.
To get started, we'll name the files after some pretend domain names. I'll create a domain called linuxonenterprise.com and another one called websysadmins.com:
cd /etc/httpd/conf.d/
touch linuxonenterprise.conf
In the linuxonenterprise.conf file, I'll add the following info:
<VirtualHost *:80>
ServerAdmin webmaster@linuxonenterprise.com
DocumentRoot "/var/www/html/linuxonenterprise/"
ServerName linuxonenterprise.com
ServerAlias www.linuxonenterprise.com
ErrorLog "/var/log/httpd/linuxonenterprise.com-error_log"
CustomLog "/var/log/httpd/linuxonenterprise.com-access_log" combined
<Directory "/var/www/html/linuxonenterprise/">
DirectoryIndex index.php index.html
Options FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
Then I'll repeat the process with a new file called websysadmins.conf. To make life easier, I can copy the linuxonenterprise.conf to websysadmins.conf.
cp linuxonenterprise.conf websysadmins.conf
And edit the websysadmins.conf file accordingly by replacing the names of the site:
<VirtualHost *:80>
ServerAdmin webmaster@websysadmins.com
DocumentRoot "/var/www/html/websysadmins/"
ServerName websysadmins.com
ServerAlias www.websysadmins.com
ErrorLog "/var/log/httpd/websysadmins.com-error_log"
CustomLog "/var/log/httpd/websysadmins.com-access_log" combined
<Directory "/var/www/html/websysadmins/">
DirectoryIndex index.html index.php
Options FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
When done, I'll exit out of my text editor and check the configuration syntax with one of the following two commands:
httpd -t
apachectl configtest
You should get an error stating that the sites don't exist at the
DocumentRoot, but we'll fix that in a second. For now, you want to get
a Syntax OK
message.
Creating the sites
The above two files tell Apache2 to look for the two websites in:
/var/www/html/linuxonenterprise
/var/www/html/websysadmins
These are the DocumentRoot, i.e., the base directories for our websites. We need to create those locations. I'll do that now for my two domains, and I'll use Bash brace expansion to create both at the same time:
mkdir /var/www/html/{linuxonenterprise,websysadmins}
The above command creates two directories:
- /var/www/html/linuxonenterprise
- /var/www/html/websysadmins
Now create some basic web pages in each domain directory:
cd /var/www/html/linuxonenterprise
echo "<h1>Linux on the Enterprise</h1>" >> index.html
Then cd
to websysadmins from the linuxonenterprise directory:
cd ../websysadmins
echo "<h1>Web Sys Admins</h1>" >> index.html
And now we have to make sure that the user apache
owns
those two directories and all future files in them. We use
the user apache
because the main Apache2 configuration file
(/etc/httpd/conf/httpd.conf
) has two directives that state that the
names of the User/Group should be apache
:
cd .. # to return to the parent directory
chgrp -R apache /var/www/html/
chmod 2775 -R /var/www/html
By adding our account to the apache
group, we can edit these and all
future files without using sudo
or becoming root
. Here I make user
'sean' part of the apache
group:
usermod -a -G apache sean
This group addition will not go into effect until the user logs out and logs back in.
You can run ls -ld
and ls -l
on those directories and files to
confirm that the apache
owner owns them. You can also run httpd -t
or apachectl configtest
again to confirm that all the syntax is good.
The Hosts File: /etc/hosts
In order to resolve IP address to domain names, we need some kind of
system that will map these two identifiers to each other. We have already
covered DNS more extensively, but since we're not really creating new
websites for the web, we'll repeat what we did in the previous weeks
with the /etc/hosts
file.
The /etc/hosts
file is like a basic DNS system and we can use as a
"static table lookup for hostnames" (from man hosts
). Let's modify
this so that our IP address is mapped to the our domain names. To do
that, let's add the following line just after the two localhost lines:
(USE YOUR IP NOT MINE)
ip a
192.168.4.32
sudo nano /etc/hosts
Then let's map the IP address to the hostnames that we'll use for the
new websites. Add the following to /etc/hosts
, but replace my IP
with yours and my hostname with one of your own creation:
192.168.4.32 linuxonenterprise.com
192.168.4.32 websysadmins.com
This is one way to create a kind of intranet that uses actual names instead of
just IP addresses. Say that you have a home network and one of the computers on
your network is running a web server. If you assign a static IP to this
computer using the software on your home router, modify the /etc/hosts
files on each of those three computers to point to that static IP via a domain
name, then you have basic DNS system for your subnet.
Now, let's restart Apache2 and see if we can visit our sites.
systemctl reload httpd.service
systemctl restart httpd.service
w3m http://linuxonenterprise.com
w3m http://websysadmins.com
Success!
If you change the /etc/hosts
file on your host machine (i.e., your
laptop) per the instructions in the last lecture, then you should be able to
visit http://linuxonenterprise.com
and http://websysadmins.com
in your
browser. Here is a snippet of what my /etc/hosts
file looks like on my
desktop machine (i.e., my host machine):
127.0.0.1 localhost
127.0.1.1 desktop
192.168.4.32 linuxonenterprise.com
192.168.4.32 websysadmins.com