Setting up virtual hosts on XAMPP* local webserver

2021-03-22 | Tutorials

This tutorial will walk you through setting up a virtual host for your PHP project. I split this tutorial in two parts - beginning with quick walkthrough, from start to finish in few steps. In the second part, I dive deep on each step of the tutorial to make sure you understand everything that you have done. I have no illusion that most of you will read the second part.

I explain the concepts from a Windows-user perspective (paths, file names). If you happen to be a unix/linux user, I am sure you know where you have your stuff and can follow along.

Why create virtual hosts?

Your PHP application will likely run on real url address, such as danieldusek.com, you want to emulate this locally and localhost just doesn't do it for you. You want danieldusek.localhost instead. Or... your application maybe doesn't handle relative paths well.

Quick step by step virtual host setup in xampp

Make sure you know:

  1. Path to your PHP project, e.g.: c:\users\username\source\mysite
  2. Path to your xampp/lampp installation, e.g.: c:\xampp

Then go and do:

  1. Open your xampp install directory and locate httpd-vhosts.conf file under apache/conf/extra folder.
  2. Open httpd-vhosts.conf file in text editor of your choice.
  3. At the very end of the file paste the following code, but replace:
  4. c:\users\username\source\mysite with actual path to your PHP project,
  5. danieldusek.localhost with your own name (do yourself a favor and use actually .localhost TLD)
<VirtualHost *:80>
    DocumentRoot "c:\users\username\source\mysite"
    ServerName danieldusek.localhost
    <Directory "c:\users\username\source\mysite">
        Require all granted
    </Directory>
</VirtualHost>

You have just configured local server to look for scripts to execute in whichever directory you chose, whenever it receives request looking for yourdomain.localhost (or whatever you have decided to go with).

Be sure to RESTART THE APACHE SERVER after saving the file.

The last step is to tell your computer to route all yourdomain.localhost requests to localhost (your computer):

  1. Open c:\windows\system32\drivers\etc folder and find hosts file
  2. Open hosts file in text editor of your choice, that can save files as administrator (Visual Studio Code can elevate to Administrator in a user friendly way when saving)
  3. Add 127.0.0.1 yourdomain.localhost line at the very end of it.
  4. Save.

When you now access yourdomain.localhost in the browser, you will see your project. If not, your setup is broken and/or you don't know what you are doing. Please proceed to the second part of this tutorial where I explain the concepts in more detail.

Step by step breakdown of what is actually going on

I decided to run an experiment where I will be explaining every concept of this tutorial and everything related to it, instead of providing troubleshooting FAQ. If my hypothesis is correct and my explanation up to par, you should be able to fix your problem on your own.

How it all works?

My basic assumption here is that you have installed an XAMPP or similar package on your device. You did that because you want to develop an application in PHP or other supported language.

XAMPP package comes with an apache server which knows how to process web requests, interpret PHP (if installed) scripts and provide content back to user sending the web requests. One of the things that apache server does while processing user's request is checking for what domain the request was sent. Remember this. Doesn't matter whether the domain name is valid or whether it exists.

When apache web server runs on a computer, it can be reached by accessing 127.0.0.1 - or its localhost alias - in the browser. Alternatively, if you happen to be connected to the internet and you have a public IP assigned to your computer, other people can send requests to your apache web server as well - they will use your public IP, instead of the localhost/127.0.0.1.

During the XAMPP / web server installation, you are allowed to choose on which ports the server will operate. By convention, http traffic will be served on port 80 and https traffic on 443. This convention is again important - these ports are well known and when your browser makes an http request, it lands on port 80 of the target server. Same it goes for https and 443. If you have chosen to use different ports for http and https traffic respectively, you will need to specify them in address.

Example scenario: You installed server to process http traffic on port 81. When you want to reach the server from your computer, you will have to access http://127.0.0.1:81.

These ports can be changed, but the process to do so would be out of scope for this tutorial. This stack overflow post does a great job at explaining how to do that.

To summarize - if you followed this tutorial, you achieved two things:

How does editing httpd-vhosts.conf works?

Let's have a look at the snippet of code that gets appended to the file:

<VirtualHost *:80>
    DocumentRoot "c:\users\username\source\mysite"
    ServerName danieldusek.localhost
    <Directory "c:\users\username\source\mysite">
        Require all granted
    </Directory>
</VirtualHost>

First thing that needs an explanation is the port number at line 1: <VirtualHost *:80>. It is 80, once again, as a side effect of the http=80 convention mentioned above. If you have installed on different port, you need to update it.

The asterisk infront of it tells the webserver to match all addresses. This can be used when you have multiple named addresses on your web server and want to fallback to the first one in case request does not match any other in the config file. Source: apache.org documentation.

The <Directory ...> are markings in a configuration language used by apache that indicate that everything inside them should be used on a given directory and all of it children directories and files. The things that are enclosed in them are called directives. Source: apache.org documentation

As for the actual directive used - Require all granted - this tells the apache server that it should not refuse to serve these pages to any IP requesting them.

In most scenarios, you will be on a local network without a public IP. So using this broad directive causes that effectively anyone on the same local network can request pages from your webserver. Should you have a public IP address, then anyone on the internet might be able to do that. If this is a concern for you, read the apache documentation and look for Require ip [IP] directive.

The ServerName yourdomain.localhost is pretty self-explanatory. Requests for given domain will be routed to the folder provided under DocumentRoot.

Why should you use .localhost TLD?

Short answer: Because you should not use an existing TLD.

Long answer: You have no control over which TLDs will be created in the future, but you can refer to RFC2606, page 2 which lists domains that you can use for private testing. These are .test, .example, .invalid, and .localhost.

How does hosts file update works?

In the second part of the local domain setup we edit the hosts file and add a 127.0.0.1 yourdomain.localhost line at the end of it. This line maps - as perceived by your computer - the yourdomain.localhost domain to 127.0.0.1 ip (your computer's ip; a localhost). You can put any domain and any IP address there instead and it will work the same way.

This is very similar to how Domain Name System (DNS) works. DNS is a protocol that maps domain names to IP addresses of computers that host websites the user is trying to reach. It is very convenient for users to type danieldusek.com instead of remembering that it is hosted on 89.221.213.23. It also gives me flexibility in changing the hosting provider without the need to tell people to now go to different address.

The hosts file is a local hint for the operating system that is used with higher priority. If a domain name is found in the hosts file, the system will not try to get the information about target IP address from the DNS server, but will use the one specified.

And that's about it.