Cheap VPS & Xen Server


Residential Proxy Network - Hourly & Monthly Packages

Configuring Tomcat5 and Apache2 with Virtual Hosts using mod_jk


Overview

This tutorial explains how I was able to setup a web server in order to support Java Server Pages (JSP) and Servlets using virtually hosted websites. Although this setup worked for this particular environment, I can make no guarantees that it will work for yours, but it should with some tweaking. I’ll explain later on. I have spent a lot of time gathering several resources in order to get this to work. Many portions of these resources have been deprecated and required a few workarounds. It is my intention that this tutorial will help anyone that has attempted to install such a system without success. If you find any inconsistencies within this tutorial, please notify me at the email address above.

Outlook

The ultimate goal is to provide instructions on how to incorporate JSP/Servlet support on the ISPConfig web hosting software. I felt it was necessary to provide this first segment separately for those that do not wish to use the ISPConfig web hosting control panel.

System Details

The system used in this tutorial has the following installed:

Operating System: Debian Sarge (3.1) http://www.debian.org/

Webserver: Apache 2.0.54 http://www.apache.org/

JDK: JDK 5.0 http://java.sun.com/j2se/1.5.0/download.jsp

Servlet Container: Tomcat http://tomcat.apache.org/

Tomcat Connector: Jakarta Tomcat Connector mod_jk (not mod_jk2)

Debian Sarge (3.1)

If you plan on utilizing ISPConfig to host your websites with Debian Sarge, I highly recommend the how-to provided by Falko Timme here: The Perfect Setup – Debian Sarge (3.1) which prepares your system to support ISPConfig. There are “Perfect Setupâ€? tutorials for other distributions as well. Otherwise, you should be able to find many other resources on the internet for installing Debian. This tutorial is specifically based on configuring Apache and Tomcat to work on Debian using the mod_jk connector.

Apache2

Since installing Apache is beyond the scope of this tutorial, I will assume that you already have Apache 2.0.x installed and running. If you need instructions on installing and configuring Apache 2.0.x please refer to the documentation at the Apache website. Again, you can also find instruction here: The Perfect Setup – Debian Sarge (3.1).

Installing JDK (Java Development Kit)

In order to run Tomcat, you will need to install JDK and set the JAVA_HOME environment variable to identify the location of the JDK environment on your system. I have chosen to use JDK 5.0.

  1. You can download JDK 5.0 at http://java.sun.com/j2se/1.5.0/download.jsp.
  1. Click on Download JDK 5.0 Update 6 to go to the download page.
  1. Click Accept to accept the license agreement.
  1. Next choose the Linux self-extracting file. This is the download for the self-extracting binary file rather than the rpm.
  1. Download to your preferred download directory. Change to that directory and make it executable by executing the following command:
chmod +x jdk-1_5_0_06-linux-i586.bin
  1. Now execute the file:
./jdk-1_5_0_06-linux-i586.bin
  1. You should now have a new directory called j2sdk1.5-sun. Now move this directory to the location where it should be run. I chose /usr/lib/.
mv j2sdk1.5-sun /usr/lib
  1. Now create a symbolic link called jdk to JAVA_HOME by the following command. This allows you to easily switch back and forth between different jvms should you ever need to
cd /usr/lib

ln -s j2sdk1.5-sun jdk

  1. Now we need to set the JAVA_HOME environment variable. Add the following at the end of /etc/profile just after export PATH.
JAVA_HOME=”/usr/lib/jdk”

export JAVA_HOME

/etc/profile is executed at startup and when a user logs into the system. In order to update the environment you will need to log out and log back in to the system.

  1. Check to make sure JAVA_HOME is defined correctly by executing the command below. This should report the location of the Java SDK which should be /usr/lib/jdk.
echo $JAVA_HOME
  1. Now test Java with the following command. You should be returned with /usr/bin/java. If so, you have successfully completed this section.
which java

Installing Tomcat

In this section you will download and install Apache Tomcat 5.5.15. For this particular setup, there is no need to build the package from source, we will download the binary version.

  1. Download the binary version to your preferred download directory from here: http://tomcat.apache.org/download-55.cgi. Choose the tar.gz from the core section for 5.5.15.
  1. Now change to that directory and extract the files using the following command:
cd /mydownloads (be sure to change to your download directory)

tar xvzf apache-tomcat-5.5.15.tar.gz

  1. You should now have a new directory called apache-tomcat-5.5.15. Now move this directory to the location where it should be installed. Again, I chose /usr/lib/. Note that this location will be referred to as CATALINA_HOME in the Tomcat documentation.
mv apache-tomcat-5.5.15 /usr/lib
  1. Next change to the /usr/lib/ directory.
cd /usr/lib
  1. Now create a symbolic link called apache-tomcat to CATALINA_HOME by the following command.
ln -s apache-tomcat-5.5.15 apache-tomcat

This will save you from having to make changes to startup and shutdown scripts each time you upgrade Tomcat and if you so desire, it also allows you to keep several versions of Tomcat on your system and easily switch amongst them.

  1. You should now be able to start and stop Tomcat from the CATALINA_HOME/bin directory. If you are using another shell other than the bash shell you will nee to add sh to the beginning of the command. You should now be able to test that Tomcat is installed by starting it and opening your browser and entering http://localhost:8080 into your browser. Port 8080 is the default port for Tomcat and can be easily changed in the /usr/lib/apache-tomcat/conf/server.xml file. (We will work with this file later on.) If you plan to access this page remotely, be sure to forward the respective port to your server’s IP address within your router. You should now see the Tomcat welcome page that contains links to Tomcat documentation as well as sample JSP/Servlet scripts. Verify that Tomcat is running by executing some of the examples found on the welcome page.
cd /usr/lib/apache-tomcat/bin

sh startup.sh

To shutdown the server, you will need to execute the following command. Feel free to try it, but for now we will leave Tomcat running.

sh shutdown.sh

Installing and configuring mod_jk

In order to make the connection between Tomcat and Apache, we will need to download and install mod_jk connector. You will find that the Apache documentation recommends that you install the packaged version of mod_jk if it is available for your particular Linux distribution. Many outdated resources recommend installing the mod_jk2 connector, but I have found that it has been deprecated and although mod_jk was developed before mod_jk2, it is still fully supported and is very stable.

Mike Millson gave some good reasoning behind using mod_jk for connecting Tomcat to Apache for Red Hat here: Integrating Tomcat and Apache on Red Hat Linux.

Here is what he had to say:

“At this point, Apache and Tomcat should be working separately in standalone mode. You can run Tomcat in standalone mode as an alternative to Apache. In fact, in some cases, it is said that Tomcat standalone is faster than serving static content from Apache and dynamic content from Tomcat. However, there are the following compelling reasons to use Apache as the front end:

1. You can use Apache to buffer slow connections. Tomcat uses java.io, which uses a thread for each request, so Tomcat can run out of connections as the number of slow requests grows. This could be an issue if your application supports a large number of dial-up users.

2. You can use a connector such as mod_jk to load balance amongst several Tomcat instances.

3. You can take advantage of Apache features such as cgi and PHP.

4. You can take advantage of Apache modules such as mod_rewrite, mod_headers, and mod_expire.

5. You can isolate virtual hosts in their own Tomcat instances.

The increased functionality obtained by using Apache on the front end can outweigh the effort required to install and configure a connector.”

At the time of this writing there were no mod_jk packages available from Dedian.org so we will need to build the package from source which will assure it is compiled for you particular installation anyways. I consider this the safer route although it requires more work.

  1. I chose to download the current source from the Apache archives: http://archive.apache.org/dist/jakarta/tomcat-connectors/jk/source/jk-1.2.15/. Download the jakarta-tomcat-connectors-1.2.15-src.tar.gz file to your /usr/src/ directory.
  1. Change to the /usr/src directory.
cd /usr/src
  1. Next, extract the contents to create the /usr/src/jakarta-tomcat-connectors-1.2.15-src directory.
tar xvzf jakarta-tomcat-connectors-1.2.15-src.tar.gz
  1. Change to the /usr/src/jakarta-tomcat-connectors-1.2.15-src/jk/native directory.
cd jakarta-tomcat-connectors-1.2.15-src/jk/native
  1. Now you are ready to create the custom configure file for your system. Execute the following:

This will create a configure file in the /usr/src/jakarta-tomcat-connectors-1.2.15-src/jk/native directory.

  1. Execute the following command in order to configure mod_jk for your system.

Important note: You will need to have apxs2 (APache eXtension tool) installed and configured with Apache. If you do not have it, as was my case, you can download and install the apache2-threaded-dev package (which replaced the former apache-dev package) from www.debian.org. At the time of this writing, the Debian package archive at www.debian.org was down and they referred me to their temporary site until they resolved their issues pdo.debian.net. I found the apache2-threaded-dev package and was able to install it successfully.

Be sure to include the correct location apxs2 on your system in the path of the command.

./configure –with-apxs=/usr/bin/apxs2
  1. Now build the mod_jk with the following:
make
  1. Finally, if you were successful with the previous commands, copy the newly created mod_jk.so to your Apache2 modules directory. My modules were located at /usr/lib/apache2/modules.
cd apache-2.0

cp /usr/src/jakarta-tomcat-connectors-1.2.15-src/jk/native/apache-2.0/mod_jk.so /usr/lib/apache2/modules

You now are ready to move to the next stage which is to begin configuring Apache and Tomcat. You can find more information about the mod_jk connector at http://tomcat.apache.org/connectors-doc/howto/apache.html.

Configure Tomcat

Create the workers.properties file

Important note: Be sure to make a backup copy of your config files before modifying.

The workers.properties file contains the details about how each process is linked to Tomcat by defining workers that communicate through the ajpv13 protocol. Refer to the Workers HowTo for more detail.

  1. First create the workers.properties file in your Apache2 root directory.
touch /etc/apache2/workers.properties
  1. Next, open the workers.properties file and ad the following. You can find many other examples of the workers.properties file on the internet, but this is the one that I created and it seems to work fine with the other portions that have already been configured in this tutorial.
workers.tomcat_home=/usr/lib/apache-tomcat

workers.java_home=/usr/lib/jdk

ps=/

worker.list=worker1

worker.worker1.port=8009
worker.worker1.host=localhost
worker.worker1.type=ajp13
worker.worker1.lbfactor=1

worker.loadbalancer.type=lb
worker.loadbalancer.balanced_workers=worker1

worker.inprocess.type=jni

worker.inprocess.class_path=$(workers.tomcat_home)$(ps)lib$(ps)tomcat.jar

worker.inprocess.cmd_line=start

worker.inprocess.jvm_lib=$(workers.java_home)$(ps)jre$(ps)lib$(ps)
i386$(ps)classic$(ps)libjvm.so

worker.inprocess.stdout=$(workers.tomcat_home)$(ps)logs$(ps)inprocess.stdout
worker.inprocess.stderr=$(workers.tomcat_home)$(ps)logs$(ps)inprocess.stderr

  1. Save and close the file.
  1. Now we need to configure the server.xml file located at /usr/lib/apache-tomcat/conf/. There are endless ways to configure the server.xml file, but I will provide to you how I did it on this server based on the other sections of this tutorial. First make a copy of your original server.xml file and rename it.
  1. Delete the original contents and add the following to the original server.xml file.
<Server port=”8005″ shutdown=”SHUTDOWN”>

<Listener className=”org.apache.catalina.mbeans.GlobalResourcesLifecycleListener” />
<Listener className=”org.apache.catalina.storeconfig.StoreConfigLifecycleListener”/>

<!– Global JNDI resources –>
<GlobalNamingResources>

<!– Test entry for demonstration purposes –>
<Environment name=”simpleValue” type=”java.lang.Integer” value=”30″/>

<!– Editable user database that can also be used by
UserDatabaseRealm to authenticate users –>
<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>

<!– Define the Tomcat Stand-Alone Service –>
<Service name=”Catalina”>

<!– A “Connector” represents an endpoint by which requests are received
and responses are returned. Each Connector passes requests on to the
associated “Container” (normally an Engine) for processing.
–>

<!– Define a non-SSL HTTP/1.1 Connector on port 2117 (default 8080) –>
<Connector port=”2117″ maxHttpHeaderSize=”8192″
maxThreads=”150″ minSpareThreads=”5″ maxSpareThreads=”75″
enableLookups=”false” redirectPort=”8443″ acceptCount=”100″
connectionTimeout=”20000″ disableUploadTimeout=”true” />

<!– Define an AJP 1.3 Connector on port 8009 –>
<Connector port=”8009″
enableLookups=”false” redirectPort=”8443″ protocol=”AJP/1.3″ />

<!– Define a Proxied HTTP/1.1 Connector on port 8082 –>
<!– See proxy documentation for more information about using this. –>
<!–
<Connector port=”8082″
maxThreads=”150″ minSpareThreads=”25″ maxSpareThreads=”75″
enableLookups=”false” acceptCount=”100″ connectionTimeout=”20000″
proxyPort=”80″ disableUploadTimeout=”true” />
–>

<!– An Engine represents the entry point (within Catalina) that processes
every request. The Engine implementation for Tomcat stand alone
analyzes the HTTP headers included with the request, and passes them
on to the appropriate Host (virtual host). –>

<!– Define the top level container in our container hierarchy –>
<Engine name=”Catalina” defaultHost=”localhost”>

<Realm className=”org.apache.catalina.realm.UserDatabaseRealm”
resourceName=”UserDatabase”/>

<!– Define the default virtual host –>

<Host name=”localhost” appBase=”webapps”
unpackWARs=”true” autoDeploy=”true”
xmlValidation=”false” xmlNamespaceAware=”false”>

<Valve className=”org.apache.catalina.valves.AccessLogValve”
directory=”logs” prefix=”localhost_access_log.” suffix=”.txt”
pattern=”common” resolveHosts=”false”/>
</Host>

<!– www.domain1.com –>
<Host name=”www.domain1.com” appBase=”/home/www/web1/web”
unpackWARs=”true” autoDeploy=”true”>

<Context path=”” docBase=”jsp-examples” debug=”0″ reloadable=”true”/>

<Valve className=”org.apache.catalina.valves.AccessLogValve”
directory=”logs” prefix=”web1_access_log.” suffix=”.txt”
pattern=”common” resolveHosts=”false”/>
</Host>

<Listener className=”org.apache.jk.config.ApacheConfig”
modJk=”/usr/lib/apache2/modules/mod_jk.so”
workersConfig=”/etc/apache2/workers.properties”/>

</Engine>

</Service>

</Server>

  1. In order to run the Tomcat auto-config you need to assure that the following line represents the appropriate locations to your mod_jk.so file and workers.properties file.
<Listener className=”org.apache.jk.config.ApacheConfig” modJk=”/usr/lib/apache2/modules/mod_jk.so” workersConfig=”/etc/apache2/workers.properties” />
  1. Restart Tomcat to create the auto-config file.

Important note: Make sure Apache2 is not running before restarting Tomcat or else auto-config will not create the config file.

cd /usr/lib/apache-tomcat/bin

sh shutdown.sh

sh startup.sh

  1. Provided you didn’t have any errors restarting Tomcat, you should have a newly created file in /usr/lib/apache-tomcat/conf/auto/ called mod_jk.conf.
  1. Now we need to open the /etc/apache2/apache2.conf file and add the following line at the bottom.
Include /usr/lib/apache-tomcat/conf/auto/mod_jk.conf

Configure Apache

Important note: Be sure to make a copy of your config files before modifying.

  1. Open your Apache2 configuration file and add the following just below the line Include /usr/lib/apache-tomcat/conf/auto/mod_jk.conf.
# Where to find workers.properties
JkWorkersFile /etc/apache2/workers.properties

# Where to put jk logs
JkLogFile /var/log/apache2/mod_jk.log

# Set the jk log level [debug/error/info]
JkLogLevel info

# Select the log format
JkLogStampFormat “[%a %b %d %H:%M:%S %Y] ”

# JkOptions indicate to send SSL KEY SIZE,
JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories

# JkRequestLogFormat set the request format
JkRequestLogFormat “%w %V %T”

# Globally deny access to the WEB-INF directory
<LocationMatch ‘.*WEB-INF.*’>
AllowOverride None
deny from all
</LocationMatch>

  1. This next section assumes you are using virtual hosts. In this system I am running ISPConfig where all of my Vhosts are defined in a separate file.

Otherwise, if you are not using ISPConfig and your Vhosts are defined within your main Apache2 config file, you just need to add this code there within the desired Vhosts that you want to utilize Tomcat (JSP/Servlets).

If you are not running Vhosts, simply add this code at the bottom of your main Apache2 config file.

For those running ISPConfig as I am, you will need to either manually place this code in the master Vhost (localhost) in the /etc/apache2/vhosts/Vhosts_ispconfig.conf or the selected Vhosts that you want to utilize Tomcat (JSP/Servlets) using the ISPConfig control panel—in the Apache Directives window for each website.

This is up to you.

For this server, I have the ISPConfig Vhosts defined in /etc/apache2/vhosts/Vhosts_ispconfig.conf.

You can either place this code after the <VirtualHost ipaddress:port> tag or just before the </VirtualHost> end tag. ISPConfig documentation recommends that you use the control panel to include any additional virtual host directives.

# Send servlet for context /servlets-examples to worker named worker1
JkMount /*/servlet/* worker1
# Send JSPs for context /jsp-examples to worker named worker1
JkMount /*.jsp worker1

Conclusion

To finalize and test this configuration you will need to copy the Tomcat example JSP files to the virtual host web directory that was defined in the server.xml, apache2.conf, and Vhosts_ispconfig.conf files. In the server.xml file you will notice that I am referencing the jsp-examples directory where jsp-examples is the name of the docbase. This will give you some idea of how the web applications will be setup for your website. You can find more details on the Tomcat website on how to generate your original web applications. In order to define another web application, you would need to define another worker (i.e. worker2) in the workers.properties file, add another host in the server.xml file, and add the same directives (using worker2 of course) to the respective VHost section.

<!– www.domain1.org –>
<Host name=”www.domain1.org” appBase=”/home/www/web2/web”
unpackWARs=”true” autoDeploy=”true”>

<Context path=”” docBase=”jsp-examples” debug=”0″ reloadable=”true”/>

<Valve className=”org.apache.catalina.valves.AccessLogValve”
directory=”logs” prefix=”web1_access_log.” suffix=”.txt”
pattern=”common” resolveHosts=”false”/>
</Host>

  1. First copy just the jsp-examples directory to web1.
cp -R /usr/lib/apache-tomcat/webapps/jsp-examples /home/www/web1/web
  1. Next you need to restart Tomcat as described earlier and then restart Apache. Remember to restart Tomcat first so you will regenerate the mod_jk.conf file.
  1. Finally test the websites by entering the respective url into your browser:
http://www.domain1.org/jsp-examples/

You should see the same jsp-examples html as you did in the default Tomcat page from earlier.

Congratulations! Your server should now be ready to support JSP/Servlets. Again, if you find any inconsistencies within this tutorial, please contact me so I can make the appropriate corrections.

Comments

comments