Apache in front of Tomcat and JBoss

Recently I have to deploy two Java web applications on a single server (one IP address). Where static content was to be served by Apache Http web server instead of Java application servers. When we have multiple applications deployed on an instance of Tomcat or JBoss we have their URLs something like


This kind of URLs does not look good when we publish it to external world. So instead of


we wanted to have URL as


This can be achieved by running applications on different instances of Tomcat / JBoss and fronting them with Apache using virtual hosts.

Running multiple instances of JBoss on a machine with single IP address is a nightmare, while it is much easier to run several Tomcat instances, as one has to change just four ports (8005, 8080, 8443, 8009). An application can be run at root context in Tomcat by adding a line like below, insideelement in$TOMCATHOME/conf/server.xml-

<context path="" docbase="appA.war" unpackWAR="false" />

There are pretty decent documentation available on Apache, Tomcat and JBoss’ website about their installation and configuration. So I will leave that discussion here itself. Though there is lots of documentation available for Apache virtual hosting also but it takes lots of effort for a newbie to do the configuration and put it in front of application servers. Here I am assuming that Apache Tomcat Connector (mod_jk) is also installed along with Apache web server.

To establish communication between Apache and application server, first we need to define connector workers as shown below-


# Define appA

# Define appB

In the above configuration appA’s server’s connector is listening on port 9009 and appB’s on 8009. This connector port is different from http port (8080 by default for Tomcat). Now define the virtual hosts, this can be done either in Apache’shttpd.confor in a separate file and include that inhttpd.conf.

NameVirtualHost *:80

LoadModule jk_module modules/mod_jk.so

# Where to find workers defined above
JkWorkersFile conf/extra/worker.properties

<virtualhost *:80>
ServerAdmin someone@domainA.tld
DocumentRoot "/path/to/the/content"
ServerName domainA.tld
ErrorLog "logs/domainA-error.log"
CustomLog "logs/domainA-access.log" common

JkMount / appA
JkMount /* appA
JkUnMount /static|/* appA

JkLogFile logs/mod_jk_appA.log
JkLogLevel info
JkLogStampFormat "[%a %b %d %H:%M:%S %Y]"
JkOptions +ForwardKeySize +ForwardURICompatUnparsed -ForwardDirectories
JkRequestLogFormat "%w %V %T"

<virtualhost *:80>
ServerAdmin someone@domainB.tld
DocumentRoot "/path/to/the/content"
ServerName domainB.tld
ErrorLog "logs/domainB-error.log"
CustomLog "logs/domainB-access.log" common

JkMount / appB
JkMount /* appB
JkUnMount /static|/* appB

JkLogFile logs/mod_jk_appB.log
JkLogLevel info
JkLogStampFormat "[%a %b %d %H:%M:%S %Y]"
JkOptions +ForwardKeySize +ForwardURICompatUnparsed -ForwardDirectories
JkRequestLogFormat "%w %V %T"

With above configuration all requests todomainA.tldare served by workerappAanddomainB.tldis served by workerappB. The ‘JkUnMount /static|/* appA’ causes any URL likehttp://domainA.tld/static/*to be served by Apache instead of the application server. As Apache performs far better while serving the static content like images, html, css, java script etc. so it is good to unmount their URLs from themod_jkworker. Most of theJk*properties can be defined out of theelement at global level, that will avoid duplicate entries. Though defining them insideelement gives flexibility to have different values for each virtual host. Detailed information aboutJk*is availablehere.

I have tested above configuration with following environment:
Java: 1.6.0_10
Tomcat: 6.0.18
JBoss: 5.0.0.GA
Apache: 2.2.11
OS: Fedora 9, Red Hat Enterprise Linux 5 and Windows Vista
Hope this will be useful to others and save their time.