Monday, December 17, 2007

Running Apache and Tomcat on the same server

Tomcat is a popular servlet container used to host java web applications. By default Tomcat listens on port 8080 (HTTP-Non SSL) and 8443 (HTTP-SSL). If your machine has multiple IPs, Tomcat will automatically bind itself to all the IPs configured.

In a production environement, there are mainly two aproaches to deploy web applications through tomcat. In the first one, the tomcat server will listen on 8080/8443 or any custom ports. All the HTTP request coming to the server (which will default to 80/443) will be received by a web server- most probably "Apache" complied with mod_jk support, or sometimes IIS. All the java related requests will be forwarded to Tomcat. Thus Apache/IIS will act as a proxy for Tomcat. The second approch, which is much more straight forward is to configure tomcat to listen on port 80/443.

With the second aproach, Tomcat will listen on port 80/443 on all configured IP addresses of the server. This is ok if you have a dedicated server for running tomcat. But it may not be the case always. In my case, when I was asked to set up Tomcat(to listen on 80/443) on one of our live servers, it was already running an apache server that serve a bunch of production web sites.

I had two choices now, either to buy a new server for hosting tomcat or to configure both apache and tomcat on the same server. I would have chosen the first option for perfomance reasons, but it was costly. So I decided to go for the later, and bought one additional public IP for the current production server.

I reconfigured apache to listen on one IP address. For this I edited

/etc/httpd/conf/httpd.conf file to change the entry
Listen 80
TO
Listen 61.17.42.50:80

AND
/etc/httpd/conf.d/ssl.conf to change the entry
Listen 443
TO
Listen 61.17.42.50:443

Now apache will listen on the IP 61.17.42.50 only.

Then I configured Tomcat to listen on the newly prcuhased IP, 61.17.42.76

The configuration file for tomcat is CATALINA_HOME/conf/server.xml where CATALINA_HOME is the installation directory for tomcat. In my case it is
/usr/apache-tomcat-5.5.17.

The file server.xml consists of a number of 'elements' enclosed in ankle brackets and a number of attributes specified for each element within those brackets.

The element that is of interest to us is "connector". There is one connector elements each for HTTP-Non-SSL and HTTP-SSL. I will quote the relevant portions of the configuration file:

HTTP Non SSL

<Connector port="8080" maxHttpHeaderSize="8192"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" redirectPort="8443" acceptCount="100"
connectionTimeout="20000" disableUploadTimeout="true" />

HTTP SSL

<Connector port="8443" maxHttpHeaderSize="8192"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" disableUploadTimeout="true"
acceptCount="100" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS" />

First, change the ports to listen on 80 and 443

<Connector port="80" maxHttpHeaderSize="8192"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" redirectPort="443" acceptCount="100"
connectionTimeout="20000" disableUploadTimeout="true" />

HTTP SSL

<Connector port="443" maxHttpHeaderSize="8192"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" disableUploadTimeout="true"
acceptCount="100" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS" />

This is not enough, because tomcat will now try to bind on ports 80 & 443 on both the public IPs. To limit tomcat to listen on 61.17.42.76 only, add an attribute "address" to both the connector elements.

<Connector port="80" maxHttpHeaderSize="8192" address="61.17.42.76"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" redirectPort="443" acceptCount="100"
connectionTimeout="20000" disableUploadTimeout="true" />

HTTP SSL

<Connector port="443" maxHttpHeaderSize="8192" address="61.17.42.76"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" disableUploadTimeout="true"
acceptCount="100" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS" />

It is not important in what order you arrange the attributes inside an element, but leave spaces between each attributes.

Now that I have apache and tomcat running on the 80/443, I can configure the DNS records for the web sites hosted in apache to point to 61.17.42.50 and DNS record for web sites to be served by tomcat to point to 61.17.42.76.

No comments:

Post a Comment