Tomcat and Virtual Hosts

In this guide I’ll go through setting up some very simple virtual hosts on an Tomcat server. This guide assumes the steps gone through to setup Tomcat 6 on Ubuntu as per this previous post.

So, the first step is to define the host under /etc/tomcat6/server.xml:

Put the above line in the Catalina “Engine” section. The “name” attribute will be used as the hostname to match and the “appBase” will define where Tomcat will look for the applications to run off of this host. If you’d like to define some aliases for this virtual host, you can do so with a nested “Alias” directive as described in the Tomcat documentation.

Next, if we want to define the Context we simply create the directory for it under Catalina:

mkdir /etc/tomcat6/Catalina/example.org

And then for a simple application we can just copy the ROOT app from the default context:

cp /etc/tomcat6/Catalina/localhost/ROOT.xml /etc/tomcat6/example.org

This will define the Context for our application. Next, we will need to create the application directory to actually hold our applications for this virtual host and copy the relevant application files to this new directory. This is done with:

mkdir /var/lib/tomcat6/example.org
cp -r /var/lib/tomcat6/webapps/ROOT /var/lib/tomcat6/example.org

Then I modified the “index.html” file under “example.org/ROOT/” to display “example.org” instead of the default “It Works!” so that we would know when the Virtual Host was being accessed. Once this is done, we can go ahead and restart Tomcat in order to apply the changes:

sudo service tomcat6 restart

To test out that this configuration is working, I added a line to my hosts file (/etc/hosts under linux) on my desktop machine to point “example.org” to the IP address of the VM that I had installed Tomcat on. This allowed me to type in http://example.org:8080 and have the request go to the Tomcat server.

If everything worked out well, going to the virtual host at http://example.org:8080 should yield the modified page, where as going to http://%5BTomcat server IP]:8080 will result in the default page.

So, there you have it, that’s the short story on how to setup up virtual hosts on Apache Tomcat.

Apache HTTP Server VirtualHost directive

Once of the things which always catches me out is the use of the VirtualHost directive in the configuration files for the Apache HTTP server. When you need to set up virtual hosting (i.e. more than one host off of the same IP, differentiated by the hostname) you need to use this directive. However, don’t make the assumption that you can do something like:

<VirtualHost http://www.example.com>…</VirtualHost&gt;

and that this will result in having a server defined for the ‘www.example.com’ hostname. The VirtualHost directive is used only to define the IP that this “virtual server” should listen on. It does not define which hostname it should reply to. While the above configuration is legal, the actual behaviour of Apache’s HTTP Server is to lookup the hostname, convert it to an IP and use that in the directive. Functionally, it is no different than doing:

<VirtualHost [IP Address of http://www.example.com host]>…</VirtualHost>

Using the hostname in this part of the configuration might lead to some unexpected behaviour. For me, I added this directive with a hostname, expecting that the configuration section would only apply to a particular hostname, when in fact it matched all hostnames using that IP.

The correct way to define a hostname based virtual host is to make use of the ServerName and additionally ServerAlias directives inside the VirtualHost stanza.