Monday, 22 March 2010

Apache and Tomcat on Ubuntu

I've had a frustrating time today, getting Tomcat working behind Apache on Ubuntu. Frustrating because there are a lot of conflicting HOWTOs, blog posts, forum posts and documentation around. Here's another! ;)

Anyway, while I remember, here's how I got it working ...

Versions

I think part of the documentation problem is down to differences between versions, so, for the record:

  • Ubuntu 9.04 Jaunty Jackalope
  • Tomcat 6.0.18
  • Apache 2.2.11
  • Java 1.6.0.16
  • mod_jk 1.2.26

All packages installed using apt-get from the Jaunty repositories.

EDIT [15th April 2010]

Since posting this, I've had a chance to confirm these instructions on Ubuntu 10.04 Lucid Lynx and, generally speaking they work OK. Differences are covered in italics at appropriate points in the text, these being the versions:

  • Ubuntu 10.04 Lucid Lynx
  • Tomcat 6.0.24
  • Apache 2.2.14
  • Java 1.6.0.18
  • mod_jk 1.2.28

Prerequisites

I'm going to assume that you have Tomcat up and running on the default port of 8080 and serving requests. Also that you have installed and tested Apache on the default port of 80, keeping the default configuration of virtual hosts as provided by the Ubuntu repositories.

Installing Apache on Ubuntu Installing Tomcat on Ubuntu

Requests are delegated from Apache to Tomcat by Tomcat listening on port 8009 for AJP1.3 requests and Apache being configured to divert some request URIs through "workers". In our case, the worker is Tomcat.

Setting up Tomcat

I've used mod_jk to connect Apache to Tomcat. It's not the only way. See the Tomcat WIKI for information on which is the recommended connector protocol.

The Ubuntu-supplied Tomcat doesn't listen for for AJP1.3 requests on port 8009 by default, so edit /var/lib/tomcat6/conf/server.xml, search for "8009" and uncomment the AJP1.3 connector module:

/var/lib/tomcat6/conf/server.xml
...
<!-- Define an AJP 1.3 Connector on port 8009 -->
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
...

Restart Tomcat, giving it time to start the listeners, and check that it is listening on port 8009:

$ sudo /etc/init.d/tomcat6 restart
 * Stopping Tomcat servlet engine tomcat6                                [ OK ] 
 * Starting Tomcat servlet engine tomcat6                                [ OK ] 
$ sudo netstat -ln | grep :8009
tcp6       0      0 :::8009                 :::*                    LISTEN     

For Lucid, restart Tomcat with $ sudo service tomcat6 restart.

If the listener is listening, Tomcat should be good to go.

Setting up Apache

To get Apache to talk to Tomcat, the first step is to install the AJP1.3 connector module mod_jk:

$ sudo apt-get install libapache2-mod-jk2

For Lucid, package is libapache2-mod-jk.

With the default Ubuntu packaging, this is all set up and should be loaded without any further intervention. The key to this is that /etc/apache2.conf includes all modules listed in /etc/apache2/mods-enabled. There's no need to add the LoadModule directive to apache2.conf as you might see quoted in some places. Such as the Tomcat documentation for example.

Then it's just a matter of configuring Apache to route some requests through to Tomcat.

The core of the Apache configuration looks like this on a default Ubuntu setup:

JkWorkersFile /etc/apache2/workers.properties
JkShmFile     /var/log/apache2/mod_jk.shm
JkLogFile     /var/log/apache2/mod_jk.log
JkLogLevel    error
JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "
JkMount /MyWebApplication/* tomcat

You have a choice at this point. You can configure this within the default virtual host that Ubuntu's Apache comes with, or globally.

If you want to configure just for the virtual host, add the above section to the bottom of /etc/apache2/sites-available/default.

If you want to configure the forwarding globally, add the above section to the bottom of /etc/apache2/apache2.conf. In this case, you also need to add an extra line to the sites-available file to get the virtual site to read the mounts. Immediately under DocumentRoot is a reasonable place.

/etc/apache2/sites-available/default
...
DocumentRoot  /var/www
JkMountCopy   On
...

The final part of the jigsaw is to set up the worker.properties file now referred to in the Apache config files. So make a new file ...

$ sudo touch /etc/apache2/workers.properties

... and edit it. With sudo of course

/etc/apache2/workers.properties
worker.list=tomcat

worker.tomcat.type=ajp13
worker.tomcat.host=localhost
worker.tomcat.port=8009

Look back at the lines we added to the Apache config files and note that the JkMount directives refer Apache to entries in workers.properties. If you had multiple Tomcat servers, you could achieve some simple application-level load balancing by routing different applications to different servers:

/etc/apache2/workers.properties
worker.list=tomcat_a, tomcat_b

worker.tomcat_a.type=ajp13
worker.tomcat_a.host=hosta
worker.tomcat_a.port=8009

worker.tomcat_b.type=ajp13
worker.tomcat_b.host=hostb
worker.tomcat_b.port=8009

Anyway, I digress. Restart Apache and you should be up and running.

$ sudo /etc/init.d/apache2 restart

For Lucid, restart Apache with $ sudo service apache2 restart.

7 comments:

Anonymous said...

This was extremely helpful!
I wanted to run tomcat behind apache
as port 8080 was externally blocked, and these
instructions worked perfectly.

I wish all howtos were as crisp as this one!
Thanks!

Anonymous said...

excellent tutorial

Jimmy Wadia said...

Very concisely presented. Wish you would post more of these how-to's.
Thanks for an excellent job.

Regards,
zorro3692@aol.com

Jimmy Wadia said...

Could you please let me know how to access my computer which runs Windows 7 Ultimate 32 bit from my other desktop which runs Ubuntu 10.04 LTS Lucid Lynx?
Samba4 does not seem to help. When I try to set up shared printer via Samba, it asks me to log on to my Windows 7 computer. I put in the correct username and password, but to no avail.
PS I can access my Ubuntu Lucid desktop from my Windows 7 easily!

Regards,

zorro3692@aol.com

Anonymous said...

Was helpful indeed.

Wolfravenous said...

I Know this is an older post but I am hoping I might still get some guidance here. I followed this wonderfully written How-to to setup tomcat and apache and It worked beautifully, until I tried to make a modification to a tomcat webapp. The modification was to move a folder of data outside of the tomcat webapp and then symlink to it. I need the data folder to reside outside the webapp so that it is accessible by another application. I can't seem to get tomcat to now follow symlinks. I have tried adding the allowlinking="true" parameter into every context.xml file that I can find using locate that deals with tomcat but it still doesn't work. Anyone have a clue what I might do to help???

Muhire Dominique said...

Thanks for the wonderfull tutorial, installation worked fine but restarting apache2 gave me the following error:

* Starting web server apache2 *
* The apache2 configtest failed.
Output of config test was:
AH00526: Syntax error on line 223 of /etc/apache2/apache2.conf:
JkWorkersFile only allowed once
Action 'configtest' failed.
The Apache error log may have more information.

Followers