Thursday, October 14, 2010

Setting Up First Tomcat JVM Instance


It is recommended not to store the web applications's files in Tomcat's distribution directory tree. For example, having a separate directory makes Tomcat upgrades easier since it won't overwrite configuration files like server.xml. And since this tutorial shows how to run two Tomcat instances concurrently on a single Linux server, two separate directories are needed anyway. It should be noted here that it's also possible to run multiple web applications per Tomcat JVM instance. This HOWTO shows the creation and configuration of one web application for each Tomcat instance.
Setting up Directories and Files

In the following example I setup the first Tomcat JVM instance under the base directory /opt/tomcat-instance/sales.example.com. It's a good practice to name the base directory after the site name, in this example sales.example.com.

Creating a new base directory for a new instance requires the creation and copying of various directories and configuration files. Execute the following commands as root:
# mkdir -p /opt/tomcat-instance/sales.example.com
# cd /opt/tomcat-instance/sales.example.com
#
# cp -a /var/lib/apache-tomcat-6.0.18/conf .
# mkdir common logs temp server shared webapps work
#
# chown -R tomcat.tomcat /opt/tomcat-instance
Most of the remaining steps are executed as the tomcat user. So make sure you switch from root to tomcat:
# su - -s /bin/sh tomcat
$ id
uid=1001(tomcat) gid=1001(tomcat) groups=1001(tomcat)
$
Next I created an environment file for the new Tomcat instance. This will be useful for easily setting the environment variables when starting/stopping the new Tomcat instance:
$ cat > /opt/tomcat-instance/sales.env << EOF
export JAVA_HOME=/usr/java/jdk1.6.0_10
export PATH=\$JAVA_HOME/bin:\$PATH
export CATALINA_HOME=/var/lib/apache-tomcat-6.0.18
export CATALINA_BASE=/opt/tomcat-instance/sales.example.com
EOF
$
$ cat /opt/tomcat-instance/sales.env
export JAVA_HOME=/usr/java/jdk1.6.0_10
export PATH=$JAVA_HOME/bin:$PATH
export CATALINA_HOME=/var/lib/apache-tomcat-6.0.18
export CATALINA_BASE=/opt/tomcat-instance/sales.example.com
$
CATALINA_HOME is the base directory of Tomcat that contains all the libraries, scripts etc. for Tomcat. This is the parent directory of the extracted Tomcat tar file.CATALINA_BASE is the base directory of the new Tomcat instance, which in this example points to /opt/tomcat-instance/sales.example.com.

Configuring Tomcat Network Ports

Since this is the first Tomcat instance that's being created here, the default port numbers can be left unchanged in $CATALINA_BASE/conf/server.xml (/opt/tomcat-instance/sales.example.com/conf/server.xml):
<Server port="8005" shutdown="SHUTDOWN">

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

    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
However, these port numbers will have to be changed for the second Tomcat instance though, see Steps for Second Tomcat JVM Instance and Application.
Starting First Tomcat Instance

To start the newly created Tomcat JVM instance, ensure that the environment variables are set for the new instance and execute the startup script:
$ source /opt/tomcat-instance/sales.env
$ $CATALINA_HOME/bin/startup.sh
Using CATALINA_BASE:   /opt/tomcat-instance/sales.example.com
Using CATALINA_HOME:   /var/lib/apache-tomcat-6.0.18
Using CATALINA_TMPDIR: /opt/tomcat-instance/sales.example.com/temp
Using JRE_HOME:       /usr/java/jdk1.6.0_10
$
If everything has been configured correctly, you should now see an empty white page when opening the URL http://localhost:8080. Note that instead of localhost you should also be able to use the name of your server.
If you get an error in the browser instead of an empty page, check the log files under $CATALINA_BASE/logs (/opt/tomcat-instance/sales.example.com/logs). Note that since CATALINA_BASE has been changed for the new Tomcat instance, the logs are no longer written to /var/lib/apache-tomcat-6.0.18/logs.
Relaying HTTP Port 80 Connections to Tomcat Port 8080

By default, Tomcat listens on port 8080. To have the Tomcat server itself listen on HTTP port 80, Tomcat would have to run as root since only root can listen on ports below 1024 on Linux. But for security reasons this is not recommended. The solution I prefer is to relay port 80 TCP connections to port 8080 using the Netfilter package that comes with Linux. An alternate solution would be to use a service wrapper like jsvc from the Jakarta Commons Daemon project. But this solution would require the installation and maintenance of another piece of software on my system that I want to avoid.

The Netfilter package that comes already with Linux is transparent to Tomcat. The following steps show how to relay port 80 TCP connections to Tomcat's port 8080 using the iptables command from the Netfilter package. Note that these steps must be executed as root:
# iptables -t nat -I PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080
# iptables -t nat -I OUTPUT -p tcp --dport 80 -j REDIRECT --to-ports 8080
The first rule redirects incoming requests on port 80 generated from other computer nodes, and the second rule redirects incoming requests on port 80 generated from the local node where Tomcat is running.

To see the newly configured rules, run:
# iptables -t nat -L
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         
REDIRECT   tcp  --  anywhere             anywhere            tcp dpt:www redir ports 8080 

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
REDIRECT   tcp  --  anywhere             anywhere            tcp dpt:www redir ports 8080 
#
To remove the NAT rules we just created, you can run the iptables -t nat -F command which flushes and deletes the rules. Note that this will also flush any other rules that may have been configured on your system! For more information on iptables, see netfilter/iptables documentation.

To make the rules permanent for reboots, you can use the following option outlined here for Debian (other Linux distributions have other methods). First save the newly created rules in a file:
# iptables-save > /etc/iptables.conf
Then edit the /etc/network/interfaces file and add the line highlighted in blue for the public network interface. For example:
iface eth0 inet static
        address 192.168.1.23
        netmask 255.255.255.0
        network 192.168.1.0
        broadcast 192.168.1.255
        gateway 192.168.1.1
        pre-up iptables-restore < /etc/iptables.conf
The pre-up configuration in this example activates the iptables rules on my system before the public interface eth0 comes up. So the rules can be seen with iptables -t nat -L after each reboot. Note that for security reasons it's important that firewall rules are established before the network interfaces come up. Even though this is not an issue for relaying Tomcat connections, as a matter of good practice, the iptables rules should always be established before the network comes up.

It should be noted here that there is one Tomcat configuration parameter that you may or may not want to change, the proxyPort parameter in the server.xml file. Since Tomcat still receives requests on port 8080 as they are relayed by the Linux Netfilter system from port 80, Tomcat may display port 8080 in the URL depending on the application's content. So if you want to change it to port 80, the proxyPort parameter would need to be added in the $CATALINA_BASE/conf/server.xml (/opt/tomcat-instance/sales.example.com/conf/server.xml). file for port 8080:
<Connector port="8080" protocol="HTTP/1.1" proxyPort="80"
               connectionTimeout="20000"
               redirectPort="8443" />
After that you need to restart Tomcat to make this change effective.
Connecting to First Tomcat Instance Using Default HTTP Port

If iptables have been configured correctly, you should now be able to open the URL http://localhost and see an empty white page. You could also use the URL http://localhost:80 (port 80 is the default port used by browsers) or the name of your server. If you get an error in the browser instead of an empty page, check the iptables configuration and check the log files under $CATALINA_BASE/logs (/opt/tomcat-instance/sales.example.com/logs). Note that since CATALINA_BASE was changed for the new Tomcat instance, the logs are no longer written to /var/lib/apache-tomcat-6.0.18/logs.

No comments:

Post a Comment