Connecting Apache to Tomcat

Two things need to happen to enable web traffic to occur between the apache web server and the Tomcat server.

  1. Apache needs to be told about how to communicate with Tomcat when needed, and
  2. Tomcat needs to be told how to listen and respond to traffic sent from apache.

Apache

Two files are involved in configuring apache to communicate with the Tomcat server.  They are used to configure the use of port 8009 and the ajp13 protocol. 

(a) Firstly the apache configuration file ( /usr/local/apache/conf/httpd.conf ) needs to be edited to include these lines:

JkWorkerFile   /usr/local/apache2/conf/workers.properties
JkLog              /var/log/apache2/jk.log            
JkShmFile       /var/log/apache2/mod_jk.shm
JkLogLevel     info

Also in this file, the url’s to be sent on to Tomcat for processing there, they need specifying.  For example, to send all traffic to a virtual host name, say “programmer.com.au“, it could look like this:

<VirtualHost 173.255.255.27:80>
        ServerName programmer.com.au
        ServerAdmin webmaster@localhost
        ErrorLog /var/log/apache2/error.log
        CustomLog /var/log/apache2/programmer_access.log combined

        # Send requests to worker named "w1", which communicates with Tomcat
        JkMount  /* w1
</VirtualHost>

Notice that all traffic under this url (“/*”) is to use the so called worker “w1”; specified with the JkMount directive.  Warning: changing the “/*” pattern to something else will probably break the current patterns Tomcat is looking for.  More about this later.

(b) The other file needed to configure apache, is a file we have called here “workers.properties”    ( which could have been called anything really ).

This file could look like this ( without the bracketed comments ):

worker.list = w1                   ( an arbitrary name - “w1” )
worker.maintain = 120        ( the default is 60 seconds )
worker.w1.type = ajp13
worker.w1.host = localhost  ( the default ) 
worker.w1.port = 8009         ( the default )

Tomcat

For Tomcat, just one file “server.xml” ( located in /usr/local/tomcat/conf ) is used to link all the web traffic between apache and tomcat, so as to be on port 8009 using the arp protocol.   

Side Tip:

Given that this is really only what we use this file to configure, everything else being standard ( in this project at least ), it is understandable that at first glance this file may appear somewhat daunting in its relative complexity. There’s a temptation then, to reduce it down to it’s bare essentials, which is possible of course.  However, some tomcat authors recommend not editing this file much, so that new versions of tomcat with possible new features, may be more easily implemented by running the unix “diff” command against the new and old versions of this file. 

However ….the tooltip

For this project on Tomcat, only one line really needs to be added to this file:

1.  Adding the port 8009 and ajp protocol:

<Connector port=”8009″ protocol=”AJP/1.3″ redirectPort=”8443″ />

Note: the redirectPort of 8443 is syntactically needed, but is only decoration and does nothing ( just in case you were wondering ).

2.  Optionally, turning off ssl as it is not needed in this project as apache is doing all the ssl encryption stuff ( but is on be default ).  The traffic between apache and tomcat is of course on the same machine so encryption between them is rather an over kill for a secure web server.

After testing, the port 8080 may also be deleted ( or commented out if preferred ).

Note: the server.xml file sets the location of the web servlets to be found in “webapps” and the log file in “/usr/local/tomcat/logs/localhost_access_log*.txt”, neither of which needs to be changed from these defaults.

# cat server.xml

<?xml version="1.0" encoding="UTF-8"?>
<Server port="8005" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.startup.VersionLoggerListener" />
<!--APR library loader. Documentation at /docs/apr.html -->
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="off" />
<!-- Prevent memory leaks due to use of particular java/javax APIs-->
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />

  <GlobalNamingResources>
     <Resource name="UserDatabase" auth="Container"
              type="org.apache.catalina.UserDatabase"
              description="User database that can be updated and saved"
              factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
              pathname="conf/tomcat-users.xml" />
  </GlobalNamingResources>

<Service name="Catalina">
 <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />

     <!-- Define an AJP 1.3 Connector on port 8009 -->
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
     <Engine name="Catalina" defaultHost="localhost">
       <Realm className="org.apache.catalina.realm.LockOutRealm">
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserDatabase"/>
      </Realm>

      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">
           <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log" suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />
      </Host>

    </Engine>
  </Service>
</Server>

© 2017, James Harry Burton. All rights reserved.