Quick Links
Apache Virtual Hosts are a feature which let you host multiple independent websites from one Apache installation. Each site has its own filesystem directory and domain name. You can serve different sites to different visitors based on the domain they're using.
Virtual Hosts are created using the
<VirtualHost>
directive in Apache configuration files. They're normally stored in the sites-available
directory within Apache's installation location. On Debian systems, this is usually
/etc/apache2
; other distributions may use
/etc/httpd
.
We'll assume you've already got Apache up-and-running. We'll create two separate Virtual Hosts, a.example.com
and b.example.com
. There's no limit to the number of Virtual Hosts you can use - if you need a dozen sites on one server, Apache will oblige.
Configuring the Sites
Each site needs its own filesystem directory. You'll place the website's files, such as HTML, CSS and JavaScript, within this directory. It's termed the DocumentRoot
by Apache, as it's the root from which documents are served.
You can locate your sites anywhere on your system. You'll often see Virtual Hosts stored within /var/www
, with each site getting its own folder:
sudo mkdir -p /var/www/a.example.comsudo mkdir -p /var/www/b.example.com
/var/www
is normally owned by root
, so we're using sudo
to create the sub-directories. Next, change the ownership of the document roots to your own user and set appropriate permissions. This will allow Apache to read files while giving you write access so you can add your content.
sudo chown -R $USER:$USER /var/www/a.example.comsudo chown -R $USER:$USER /var/www/b.example.com
sudo chmod -R 755 /var/www
Copy your website files into the directories. We'll use two simple index.html
files:
a.example.com/index.html
<html><body>
<h1>a.example.com</h1>
</body>
</html>
b.example.com/index.html
<html><body>
<h1>b.example.com</h1>
</body>
</html>
Configuring Apache
Now you're ready to configure your Virtual Hosts. Create a new Virtual Host file for each of the sites. It doesn't matter what you name the file; by convention, it usually matches your site's hostname.
At minimum, each Virtual Host needs to declare two properties:
-
ServerName
- The hostname (domain) that the site is going to be served from. -
DocumentRoot
- The filesystem location to serve for this Virtual Host.
Here's an example configuration for our two sites:
/etc/apache2/sites-available/a.example.com.conf
<VirtualHost *:80>ServerName a.example.com
DocumentRoot /var/www/a.example.com
</VirtualHost>
/etc/apache2/sites-available/b.example.com.conf
<VirtualHost *:80>ServerName b.example.com
DocumentRoot /var/www/b.example.com
</VirtualHost>
This basic setup is enough to get the two sites live! The *:80
means Apache will consider using this Virtual Host for any request arriving on port 80. They'll be disambiguated later on by the ServerName
declarations.
Enabling Virtual Hosts
Adding a Virtual Host to sites-available
makes it available but not active. You need to manually enable each site you want to use. Virtual Host configs to enable should be symlinked into /etc/apache2/sites-enabled
(or /etc/httpd/sites-enabled
).
On Debian systems, you can use the a2ensite
command to simplify this step:
a2ensite a.example.coma2ensite b.example.com
On other distributions, use the ln
command to create a symlink manually.
sudo ln -s /etc/httpd/sites-available/a.example.com.conf /etc/httpd/sites-enabled/a.example.com.confsudo ln -s /etc/httpd/sites-available/a.example.com.conf /etc/httpd/sites-enabled/b.example.com.conf
Finally, restart Apache to apply your new configuration. Virtual Host changes require a server restart after you've added them to sites-enabled
.
sudo apache2ctl restart
You should now be able to see Apache serving your two different sites. If you've not got DNS resolving to your server, you can modify your system's /etc/hosts
file to test your setup.
Add the following lines to /etc/hosts
:
127.0.0.1 a.example.com127.0.0.1 b.example.com
This will force both domains to resolve back to your own system. You'll now be able to visit them in your browser to see the two different Virtual Host pages.
Site Aliases
If you want to serve the same site on multiple domains, use the ServerAlias
directive in your Virtual Host. Each alias will be considered when Apache matches your Virtual Host against incoming requests. The Virtual Host will be used if the request's Host
header matches a ServerAlias
or the ServerName
.
<VirtualHost *:80>ServerName a.example.com
ServerAlias example.com
ServerAlias www.example.com
DocumentRoot /var/www/a.example.com
</VirtualHost>
This example would serve the a
site on three domains, without having to repeat any configuration details. You must use ServerAlias
to define multiple domains - repeating ServerName
is possible but it will override the earlier uses.
Other Configuration Options
Many of Apache's server configuration options can be used with Virtual Hosts. They'll override the global server settings when Apache handles a request using the Virtual Host.
<VirtualHost *:80>ServerName a.example.com
DocumentRoot /var/www/a.example.com
DirectoryIndex my-index.html
<Directory /var/www/a.example.com>
AllowOverride All
Options -Indexes
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
This Virtual Host applies many more settings. my-index.html
is served by default, instead of index.html
, and custom logging locations are used. In addition, extra settings are applied to the document root itself, using the Directory
block. .htaccess
overrides are permitted (AllowOverride All
) and Apache's default directory listing pages are disabled (Options -Indexes
).
IP Address Hosts
Apache also supports IP-based hosts besides the name-based hosts we've seen so far. IP-based hosts are ideal when your server has multiple network interfaces, such as an internal company network and the public internet. You can serve a different site depending on the network interface used.
<VirtualHost 172.17.0.1>ServerName a.example.com
DocumentRoot /var/www/a
</VirtualHost>
<VirtualHost 172.17.0.1>
ServerName b.example.com
DocumentRoot /var/www/b
</VirtualHost>
<VirtualHost 192.168.0.1>
ServerName a.example.com
DocumentRoot /var/www/a2
</VirtualHost
In this example, requests made to a.example.com
via the interface with IP 192.168.0.1
would receive different content to those sent via 172.17.0.1
. In addition, users of the latter IP would be able to access b.example.com
. This site isn't exposed to users connecting via 192.168.0.1
.
This approach lets you use one server for your corporate intranet and public website. Bind the internal sites to your server's LAN IP; run the public hosts against its WAN address.
Virtual Host Matching
Apache's Virtual Host resolution routine is well-documented and quite straightforward.
In general, Apache tries to match the Host
request header against a ServerName
or ServerAlias
field in a Virtual Host configuration. If there's multiple matches, Apache will use the first matching Virtual Host it found.
Virtual Hosts are sorted in order of filename. If you need a site to match before another, rename its configuration file so it'll sort before the target site. You can add a numerical prefix such as 000-a.example.com.conf
. Most of the time this will be unnecessary - if all your sites have unique domains, you should never encounter a conflict.
Conclusion
Apache Virtual Hosts let you break down multi-site configuration into self-contained definition files. You can independently enable and disable each site by linking it into sites-enabled
.
Many configuration options are available for Virtual Hosts. You can override some Apache server settings on a per-host basis, so you have full control over each virtualised site setup.