There are times when you need to run multiple instances of Tomcat on the same Linux based server. My need came as I tried to run Jive Clearspace, Jira, and Bamboo all on the same instance of Tomcat in different directories. The first thing I noticed was that the logs were cluttered with all sorts of conflicting classes. The next thing I noticed was that the reporting graphs in Bamboo were not displaying. As I took my issues to Atlassian, they informed me that Bamboo and Jira have conflicting ognl files and cannot be run to on the same instance of Tomcat. Hence, I was in the situation where I needed to run separate instances of Tomcat to get the applications to work.
Don’t be overwhelmed. Once you have gotten one Tomcat instance to work with Apache, the second (and third for that matter) is no big deal.
By the way, this is all being run on a dedicated CentOS Linux server sitting in the racks of Godaddy.
Download Tomcat
Go ahead and download Apache Tomcat and store them in separate locations. For example:
/var/tomcat/jira
/var/tomcat/bamboo
/var/tomcat/clearspace
Go ahead and download Tomcat into each of the directories:
wget http://download.nextag.com/apache/tomcat/tomcat-6/v6.0.26/bin/apache-tomcat-6.0.26.tar.gz (or whatever the latest version is at the time)
Deconflict the Ports
There are three ports which need to be deconflicted which are all configured in the server.xml file in the conf directory for each Tomcat installation.
1. The shutdown port – default 8005
2. The connector port – default 8080
3. The AJP port – default – default 8009
So you might as well designate the first to use the default ports, and the second to use port 8006, 8081, and 8010 (and the third using port 8007, 8082, and 8011). Simply change those numbers in the server.xml file.
<Server port="8005" shutdown="SHUTDOWN">
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
It is a good idea at this time to make certain that each of these instances can be started up and the default page viewed one at a time. Start the first one, test it, and then stop it. This is done by going to the bin directory and invoking ./startup.sh and ./shutdown.sh.
To test each one, use the appropriate command
wget http://localhost:8080
wget http://localhost:8081
wget http://localhost:8082
and simply see that each command downloads the index.jsp page with the default Tomcat page written to file.
Now make certain that stop each instance of Tomcat before starting and testing the next one – otherwise, you will have conflicting CATALINA_HOME variable values which should break things.
Establish Ownership and Create Startup Files
What originally concerned me about running multiple instances of Tomcat was that each instance needs a unique CATALINA_HOME environment / user variable. It use to be that you were required to establish the CATALINA_HOME as a variable in order to start the application. Today, if you do not have it defined, the application will assign it automatically during the startup process. So now you need to create a startup script which assigns the application to be automatically started by its own user.
In this example, create three users on your Linux operating system – clearspace, jira and bamboo. Go ahead and assign these three users a password. Then run the chown -Rf command to assign ownership of each application and all of the files to the appropriate user. Go to the
/var/tomcat
directory and call from the root user
chown -Rf bambo.bamboo bamboo/
chown -Rf jira.jira jira/
chown -Rf clearspace.clearspace clearspace/
Now create a startup script in the /etc/init.d directory for each of these. This particular script works for me.
Notice the /bin/su bamboo command. Replace bamboo with the appropriate user name which specifies the user you want to run the application as.
vi bamboo
#!/bin/sh
#
# Tomcat Server
#
# chkconfig: 345 96 30
# description: Java servlet container
TOMCAT_START=/var/tomcat/bamboo/apache-tomcat-6.0.26/bin/startup.sh
TOMCAT_STOP=/var/tomcat/bamboo/apache-tomcat-6.0.26/bin/shutdown.sh
start()
{
if [ -x ${TOMCAT_START} ]; then
echo “Starting bamboo server…”
/bin/su bamboo $TOMCAT_START &
else
echo “Cannot start bamboo server”
fi
}
stop()
{
if [ -x ${TOMCAT_STOP} ]; then
echo “Stopping bamboo server…”
/bin/su bamboo $TOMCAT_STOP &
else
echo “Cannot stop bamboo server”
fi
}
restart()
{
stop
sleep 10
start
}
status()
{
echo “No status available for tomcat server”
}
case “$1″ in
’start’)
start
;;
’stop’)
stop
;;
‘restart’)
restart
;;
’status’)
status
;;
*)
echo “Please supply an argument [start|stop|restart]”
esac
Do the same for all three applications.
After creating the unique files for each application, you will want to call the chkconfig command to establish these files to autostart when the server gets a physical reboot. While this is an optional step, it is necessary if you want the applications to automatically come up when the server gets rebooted. You can choose to do this later once you have completed all troubleshooting.
Now you can start up each instance of Tomcat logged in as the root user by starting each Tomcat instance as a service.
cd /etc/init.d
./bamboo start
./clearspace start
./jira start
Now check that all three are running by either using a browser or the wget command from the command prompt. Using the command prompt is the most reliable as a firewall my be blocking your browser from accessing the non-standard ports.
wget http://localhost:8080
wget http://localhost:8081
wget http://localhost:8082
You should see that you get the default Tomcat page from each of these wget calls just like you did before.
Get them working with Apache
Now that each instance of Tomcat is running, you need to get all three of them to work with Apache. Not intending to replace the Apache documentation, here is what you need to do in a nutshell.
Download the mod_jk libraries, place it into the modules directory (/etc/httpd/modules), rename it, and make it executable.
cd /etc/httpd/modules
wget http://apache.cs.utah.edu/tomcat/tomcat-connectors/jk/binaries/mod_jk-1.2.30-httpd-2.0.53.so (this may be different)
mv mod_jk-1.2.30-httpd-2.0.53.so mod_jk.so
chmod 755 mod_jk.so
Now add the following to your httpd.conf file (more details of where to get the files is in the Tomcat documentation). Place it immediately below the rest of where the LoadModule commands are listed.
LoadModule jk_module modules/mod_jk.so
jkWorkersFile /etc/httpd/conf/workers.properties
jkMountFile /etc/httpd/conf/uriworkermap.properties
JkShmFile /var/log/httpd/mod_jk.shm
JkLogFile /var/log/httpd/mod_jk.log
JkLogLevel info
JkLogStampFormat “[%a %b %d %H:%M:%S %Y] ”
Next, create the workers.properties file in the specified location you just added to the httdp.conf file and add the following lines to it.
# Define real workers using ajp13
worker.list=worker1, worker2, worker3
# Set properties for workers (ajp13)
worker.worker1.type=ajp13
worker.worker1.host=localhost
worker.worker1.port=8009
worker.worker2.type=ajp13
worker.worker2.host=localhost
worker.worker2.port=8010
worker.worker3.type=ajp13
worker.worker3.host=localhost
worker.worker3.port=8011
The contents of the uriworkermap.properties are optional depending on your applications. You can remove it from the httpd.conf file but for now it is best to include it and create a blank uriworkermap.properties file.
Configure and Start Apache
Now go back to your httpd.conf file and establish the workers in the appropriate sites:
NameVirtualHost 173.201.176.190:80
<VirtualHost 173.201.176.190:80>
ServerAdmin brian@trisummit.net
ServerName clearspace.trisummit.net
ErrorLog logs/clearspace.trisummit.net-error_log
CustomLog logs/clearspace.trisummit.net-access_log common
jkMount /* worker1
</VirtualHost>
<VirtualHost 173.201.176.190:80>
ServerAdmin brian@trisummit.net
ServerName jira.trisummit.net
ErrorLog logs/jira.trisummit.net-error_log
CustomLog logs/jira.trisummit.net-access_log common
jkMount /* worker2
</VirtualHost>
<VirtualHost 173.201.176.190:80>
ServerAdmin brian@trisummit.net
ServerName bamboo.trisummit.net
ErrorLog logs/bamboo.trisummit.net-error_log
CustomLog logs/bamboo.trisummit.net-access_log common
jkMount /* worker3
</VirtualHost>
Now restart apache. As long as your DNS settings are correct (or Hosts file), you should access the default Tomcat page from all three of the appropriate URLs all over port 80 through Apache. Congratulations, you did it.