C2B2 logo icon

How to Create Multiple Tomcat Instances on the Same Server

Head of Middleware Support, Claudio Salinitro describes how to scale up your infrastructure with multiple Tomcat instances in just a few minutes!

Recently, one of our Managed Services customers in the e-commerce sector undertook a new project which required scaling up their existing Tomcat infrastructure. 

Because we provide fully managed middleware support for their application deployment, and have an in-depth knowledge of their systems and business processes, we were able to bring in our consultancy team to design and deliver a roadmap for an AWS cloud migration.

When I was talking with their in-house team about some of the issues, one of the developers asked about creating multiple Tomcat instances. It struck me as a useful topic to explore, and gave me the idea to write a short walk-through for anyone who might be looking at deploying multiple Tomcat instances.

Installing a single Tomcat instance is a simple and straightforward practise, but things become a little more complex if you want to isolate different Tomcat applications on several dedicated instances. 

In theory, you can just keep duplicating the Tomcat files, but the more instances you have, the more the effort required to maintain several parallel installations increases.

So, let’s see how to do it in a more efficient way!

The software I used in this scenario was:

  • Apache Tomcat (8.5.16)
  • jdk1.8.0_121

Folders Set-Up

Let’s start from a standard Tomcat installation, and take the Tomcat binaries (or the sources) from the Tomcat website: https://tomcat.apache.org/download-80.cgi

Also we need a JDK, I’m using Tomcat 8.5, so any jdk version from and including 7 is fine. If you're using a different version, then just check that it's supported by your installation here: http://tomcat.apache.org/whichversion.html 

When you copy Tomcat and jdk to your server, and decompress the packages, you should see something like this:

[tomcat@centos1 tomcat]$ pwd
/opt/tomcat
[tomcat@centos1 tomcat]$ ls -ltr
total 188152
drwxr-xr-x. 5 tomcat 1001       112 Jul 21 15:28 apache-tomcat-8.5.16
drwxr-xr-x. 8 tomcat 1001       255 Dec 13  2016 jdk1.8.0_121

Now, the apache-tomcat-8.5.16 folder contains a fully working Tomcat server. 

We will keep this folder as a location for our binaries (CATALINA_HOME) while we will create a folder for each tomcat instance we need (CATALINA_BASE), and inside each instance folder we will need to create the following directories:

  • bin
  • conf
  • logs
  • temp
  • webapps
  • work

If everything is correct, you should have a structure like the one below:

[root@centos1 instances]# pwd
/opt/tomcat/instances
[root@centos1 instances]# tree
.
├── tomcat1
│   ├── bin
│   ├── conf
│   │   └── Catalina
│   │       └── localhost
│   ├── logs
│   ├── temp
│   ├── webapps
│   └── work
└── tomcat2
    ├── bin
    ├── conf
    │   └── Catalina
    │       └── localhost
    ├── logs
    ├── temp
    ├── webapps
    └── work
18 directories, 0 files

Now, copy the content of the conf folder and the webapps folder from CATALINA_HOME to your instances folders:

cp -pr /opt/tomcat/apache-tomcat-8.5.16/conf /opt/tomcat/instances/tomcat1/
cp -pr /opt/tomcat/apache-tomcat-8.5.16/webapps /opt/tomcat/instances/tomcat1/
cp -pr /opt/tomcat/apache-tomcat-8.5.16/conf /opt/tomcat/instances/tomcat2/
cp -pr /opt/tomcat/apache-tomcat-8.5.16/webapps /opt/tomcat/instances/tomcat2/

And also copy the $CATALINA_HOME/bin/catalina.sh, $CATALINA_HOME/bin/shutdown.sh and $CATALINA_HOME/bin/startup.sh to the bin folder of your CATALINA_BASE folders:

cp -pr /opt/tomcat/apache-tomcat-8.5.16/bin/catalina.sh /opt/tomcat/instances/tomcat1/bin
cp -pr /opt/tomcat/apache-tomcat-8.5.16/bin/startup.sh /opt/tomcat/instances/tomcat1/bin
cp -pr /opt/tomcat/apache-tomcat-8.5.16/bin/shutdown.sh /opt/tomcat/instances/tomcat1/bin
cp -pr /opt/tomcat/apache-tomcat-8.5.16/bin/catalina.sh /opt/tomcat/instances/tomcat2/bin
cp -pr /opt/tomcat/apache-tomcat-8.5.16/bin/startup.sh /opt/tomcat/instances/tomcat2/bin
cp -pr /opt/tomcat/apache-tomcat-8.5.16/bin/shutdown.sh /opt/tomcat/instances/tomcat2/bin

Almost done!

To finish the set-up, all you now need to do is create a new file (setenv.sh) inside the bin folder of each CATALINA_BASE folder, using the following content:

JAVA_HOME=/opt/tomcat/jdk1.8.0_121
CATALINA_HOME=/opt/tomcat/apache-tomcat-8.5.16
CATALINA_BASE=/opt/tomcat/instances/tomcat1

Remember to change the CATALINA_BASE accordingly!

Technically, the structure is now complete, but if we try to start two instances together, we will find an error with the second, because we didn't change the listening port of the second instance!

Let’s edit the $CATALINA_BASE/conf/server.xml and change the port value of each active connector you have in your configuration, and the shutdown port. In this case this is the diff between the server.xml files of two different instances:

[root@centos1 conf]# diff server.xml  ../../tomcat1/conf/server.xml
22c22
< <Server port="8006" shutdown="SHUTDOWN">
---
> <Server port="8005" shutdown="SHUTDOWN">
69c69
<     <Connector port="8081" protocol="HTTP/1.1"
---
>     <Connector port="8080" protocol="HTTP/1.1"
71c71
<                redirectPort="8444" />
---
>                redirectPort="8443" />
116c116
<     <Connector port="8010" protocol="AJP/1.3" redirectPort="8444" />
---
>     <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

Summing Up...

With this set up, we'd be able to spawn several instances each dedicated to a single or a group of applications. Now, updating one, some or all the instances becomes easier to manage, and is just a matter of updating the setenv.sh file to use the proper CATALINA_HOME for the binaries and libraries.

Of course, this is a simple scenario. In the real-world project, the next step would be to integrate the set-up with an automation tool such as Ansible, Chef or Puppet to provide reduce release times, manage workloads, and provide optimal control over infrastructure administration.

And, the great thing from a support perspective is that when a customer we work so closely with on business-as-usual activities is looking ahead to a new project, our knowledge of their business processes and systems means that we can work with our delivery team on their behalf.