Page tree

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Table of Contents

Introduction

This is a method of installing and running Tomcat in a way that is portable and part of the BonsaiFramework BonsaiFramework 0FS approach. Tar (zip) up the directory and move your entire application server or duplicate it with a copy command.

This work comes from a corporate environment where isolation, control and ease of upgrade with a fallback are very important. Also, allows for fast horizontal or vertical scaling where multiple Tomcat instances are run on the same machine. This work also is the fundation for understanding and moving towards cloud techniques such as Tomcat based Docker.

This article gives an example of setting up 2 Tomcat instances using the same version of Java,

  • Tomcat1 on Java 1.6.0_16 run by user serveradmin
  • Tomcat2 on Java 1.6.0_16 run by user serveradmin

You may also opt to further mix and match with different versions of Tomcat and Java

Also this also sets your application to moving towards cloud containor implementations like LXC or Docker.

The key concept here is that we setup Tomcat and Java as an isolated package. There is no install. As long as you have matching serveradmin GUID's across systems you may transport your package with tar.

Software Stack Selection,

...

Gliffy Diagram
borderfalse
nameMultiple Tomcat Instances
pagePin10

Shortcut

Everything is all packaged up at http://www.bonsaiframework.com/downloads/0fs-tomcat-linux/,

Package VersionCommentsNext Step Version
v0.1Basic Tomcat with Java embedded. This should be run only as serveradmin per the Bonsai approach to server management.Ongoing Maintenance with new versions of Java and documentation of who's using it and where.
v0.2Harden Tomcat and maintain a log.... will be done as part of the Bonsai group work ...
v0.3Rolling LogsFix catalina.outlog rotation (determine best route) and petition to get this fixed. Kevin looking into this.

Install by unzipping as serveradminan unzip using a staff account. The use of sudo is necessary to retain permission,

Code Block
languagebash
wget http://www.bonsaiframework.com/downloads/0fs-tomcat-linux/0fs-tomcat.tar.gz # this symbolically points to the latest 64-bit version

# NOTE - to work properly ensure serveradmin is setup per Bonsai instructions!
#

sudo tar -xvpf 0fs-tomcat.tar.gz

Then as a sudo user,

Code Block
languagebash
 # sudo will ensure the permissions and users are kept
sudo mv /home/serveradmin0fs-tomcat/ /opt/


# Optionally if you want to follow the Bonsaiframework convention and also let users belonging to "staff" group to view files and restrict others,
cd /opt/
sudo chown -R serveradmin:staff ./0fs-tomcat/
sudo chmod -R o-rwx ./0fs-tomcat/
sudo chown -R serveradmin.staff ./0fs-tomcat/

You are now ready to go and start Tomcat as serveradmin,

Code Block
su - serveradmin
cd /opt/0fs-tomcat/bin/
.1/startup.sh

...

Verify Tomcat is running,

Code Block
languagebash
ps -ef | grep java

To stop Tomcat,

Code Block
languagebash
sudosu tar -czvf  serveradmin # if not already serveradmin
cd /opt/0fs-tomcat.tar.gz/bin/
./0fs-tomcat/shutdown.sh

That's it.

Tomcat and serveradmin

I will re-iterated that you should run Tomcat or any public facing service for that matter as serveradmin. As noted in account creation, this is for security reasons. In the event that Tomcat is somehow attacked, the compromise would be limited to serveradmin which has reduced limited priviledges.

Further to this, using a central account ensures consistency.

For audit purposes, make sure to log in with your own staff id first and then sudo into serveradmin for managing Tomcat. In true Cloud world where everything works as a recipe, use your recipes to make Tomcat adjustments.

Directory Structure

The directory structure will be as follows,

/opt/ apache - root directory for Tomcat and any other Apache productsall our applications and services (anything custom if possible should be here)

/opt/apache/0fs-tomcat .1 - directory for Tomcat1 Tomcat running on port 8180
/opt/apache/tomcat.1/java - directory we will place java for Tomcat1/opt/apache/tomcat.2 - directory for Tomcat2
/opt/apache/tomcat.2/0fs-tomcat/java - directory we will place java for Tomcat2 running on port 8280Tomcat

First step, create the apache directory under opt,

Code Block
languagebash
su - bhitch # We need a staff user who can sudo
cd /opt
sudo mkdir apache
sudo chown -R serveradmin:serveradminstaff ./apache # Make sure serveradmin can use the folder.

Manually Setup JRE

Include Page
9.0 Zero Footprint Java on Ubuntu
9.0 Zero Footprint Java on Ubuntu

Leave the setup Java folder alone for now. It will be moved into the Tomcat folder as part of the Tomcat setup.

Manually Setup Tomcat and Package Java In

By manually setting up Tomcat there is much more control and you can run multiple tomcat instances. Download tomcat. The tar.gz file is used because permissions are already setup such as execute for for startup.sh. A zip file will lose the permissions.

...

Code Block
languagebash
su - serveradmin
cd ~
gunzip apache-tomcat-6.0.20.tar.gz tar -xvpf apache-tomcat-6.0.20.tar.gz # All the permissions will be kept
mv ./apache-tomcat-6.0.20/ ./0fs-tomcat.1/
# This will be Tomcat1
exit # Switch back to your staff account

...

Code Block
languagebash
mv ./java/ ./0fs-tomcat.1/

Log in as your staff account which has sudo access to perform the actual move to /opt/

Code Block
languagebash
sudo mkdir /opt/apache # just to organize things a bit better
cd /home/serveradmin
sudo mv ./tomcat.1/ /opt/apache/

Finally, if this is a multi-user machine, we secure tomcat from other users and processes. The only users should be serveradmin for read and write and staff for read to debug.

Note

I'll be writing an improved article that uses ACLs in the future that deals with permissions better.

Change the permissions,

Code Block
languagebash
cd /opt/apache
sudo chown -R serveradmin:staff ./tomcat.1/
sudo chmod -R o-wrx ./tomcat.1/

Change Default Ports

We will change Tomcat1 from the default ports,

  • 8005 - for shutdown
  • 8009 - for JK Mod
  • 8080 - regular port similar to 80
  • 8443 - ssl port similar to 443

The new ports will be,

  • 8105 - for shutdown
  • 8109 - for JK Mod
  • 8180 - regular port similar to 80
  • 8543 - ssl port similar to 443

The very first step is to verify that the ports for Tomcat1 are not being used.

Code Block
netstat -an | grep LISTEN | grep 8105
netstat -an | grep LISTEN | grep 8109
netstat -an | grep LISTEN | grep 8180
netstat -an | grep LISTEN | grep 8543

If you get no results then there are no listening ports.

Change Tomcat1 to use use the new ports by editing /opt/tomcat.1/conf/server.xml. Use an editor to search and replace or more quickly using the following sed commands to do modify your file,

Code Block
cd /opt/apache/tomcat.1/conf/
sed -i 's/8005/8105/' server.xml
sed -i 's/8009/8109/' server.xml
sed -i 's/8080/8180/' server.xml
sed -i 's/8443/8543/' server.xml

Fix Tomcat catalina.out Logging

Tomcat Logging has a bug where if catalina.out reaches over (question) (need to research) logging stops working. Worse if over 2GB Tomcat will not start and also not report any errors. Yes this is pretty crazy that this is not fixed.

Ubuntu

Edit the bin/catalina.sh,

Code Block
languagebash
cd /opt/apache/tomcat.1/bin/
 
# For Tomcat 8
 
# Turns off the creation of the generic file.
sed -i 's/touch "$CATALINA_OUT"/#touch "$CATALINA_OUT"/' catalina.sh
 
# Uses cronolog to rotate.
sed -i 's/>> "$CATALINA_OUT" 2>&1 "&"/2>&1 |/usr/bin/cronolog "$CATALINA_BASE/logs/catalina-%Y-%m-%d.out" &/' catalina.sh

This solution comes from VMWare who now owns SpringSource. Caveat is that the incorrect process ID being written to the process ID file so I don't like this solution as it will impact shutdown scripts.

Windows

Warning

TBC - Research and a solution needs to be found for this.

This article by SpringSource uses cronolog (they know Tomcat so well they created a variation with more Enterprise features looks promising").

Apache Tomcat's position is to not fix in the near future (we disagree as enough restarts will cause the problem with the log file) and the same article also provides some solutions too.

Research

http://java.dzone.com/articles/how-rotate-tomcat-catalinaout?utm_source=am6_feedtweet&utm_medium=twitter&utm_campaign=toya256ForRSS - talks about using logrotate (there is a slice of time where the log stops working). Also has a patch to tomcat so this solution works in Solaris.

Posting at bottom talks about a bug with Bash with logrotate and how to solve - http://java.dzone.com/articles/how-rotate-tomcat-catalinaout

Article by Spring Source using cronolog - http://www.tomcatexpert.com/knowledge-base/rotating-catalinaout-log-files

Naming the Tomcat Process for Solaris (solved)

Solaris' built in ps has a specific limitation of 60 characters. As a result, it is not intuitive to determine which process of tomcat is which when the ps command is executed,

Code Block
serveradmin 12150 13290   1 11:51:28 pts/2       0:10 /opt/jre1.6.0_16/bin/java -Djava.util.logging.manager=org.apache.juli.ClassLoad
serveradmin  5906 13290   0   Jul 24 ?           6:17 /opt/jre1.6.0_16/bin/java -Djava.util.logging.manager=org.apache.juli.ClassLoad

Notice that the names are exactly the same.

Using the Bonsai Framework method of bundling Java with Tomcat we can tell the differences,

Code Block
languagebash
serveradmin 12150 13290   1 11:51:28 pts/2       0:10 /opt/apache/tomcat.1/java -Djava.util.logging.manager=org.apache.juli.ClassLoad
serveradmin  5906 13290   0   Jul 24 ?           6:17 /opt/apache/tomcat.2/java -Djava.util.logging.manager=org.apache.juli.ClassLoad
0fs-tomcat/ /opt/apache/

Only Allow serveradmin to Run Tomcat

Setting up and running Tomcat with serveradmin has the advantage that you can manage the Application server without having to go into root. It's also makes things much safer if somebody breaks into Tomcat.

We want to ensure that only serveradmin starts Tomcat to prevent any issues with permissions. For example, once you start Tomcat1 as Tomcat as root you may find that log files spawned from that during startup can no longer be managed by serveradmin. Also, by running Tomcat1s serveradmin rather than root is safer from a security standpoint.

Note

I may have come up with a better strategy where others can not execute and the below script is no longer necessary. hmm.... got to test and ensure root can not override this.

First login as serveradmin. All modification to Tomcat and running of tomcat will happen as serveradmin.

Code Block
su - serveradmin

Modify Tomcat1Tomcat's /opt/apache/0fs-tomcat.1/bin/startup.sh and opt/apache/0fs-tomcat.1/bin/shutdown.sh to only allow serveradmin to start and stop Tomcat.

Do this by adding the block of lines marked with # Bonsaiframework as shown below,

Code Block
languagexmlbash
#!/bin/sh

# Bonsaiframework - Modification Start
# --------------------------------------
if [ "$LOGNAME" != "serveradmin" ]; then
echo "This service should only managed with the user serveradmin"
exit 1
fi
# --------------------------------------
# Bonsaiframework - Modification End

# Licensed to the Apache Software Foundation (ASF) under one or more

...

Tip
Challenge to a reader after learning this. Make the above edit automated with copy and paste with sed and wget like my other tutorials.

Bind Tomcat to Java Using setenv.sh

Tomcat can be run with a separate version of JRE or JDK that is not the default system version. To do so, you will have to explicitly set the JRE_HOME variable. The JAVA_HOME variable is also configured as some applications will want to make use of this variable instead.

Tomcat has a nice facility for this via a file called setenv.sh which actually does not exist by default. As soon as you create the file, Tomcat will run setenv.sh as part of its startup.

...

Code Block
languagebash
su - serveradmin # If you are not already serveradmin.
cd /opt/apache/0fs-tomcat.1/bin
./version.sh
Neither the JAVA_HOME nor the JRE_HOME environment variable is defined
At least one of these environment variable is needed to run this program

So now let's create the setenv.sh file. As serveradmin create /opt/apache/0fs-tomcat.1/bin/setenv.sh using your favourite editor. Your file contents will look like this,

...

The $CATALINA_HOME is a script variable that is established by Tomcat to set the directory it is running from.

Now when you use  exeucting version.sh you will see the following resultsworks,

Code Block
languagebash
./version.sh
Using CATALINA_BASE:   /opt/apache/0fs-tomcat.1
Using CATALINA_HOME:   /opt/apache/0fs-tomcat.1
Using CATALINA_TMPDIR: /opt/apache/0fs-tomcat.1/temp
Using JRE_HOME:       /opt/apache/0fs-tomcat.1/java
Server version: Apache Tomcat/6.0.20
Server built:   May 14 2009 01:13:50
Server number:  6.0.20.0
OS Name:        Linux
OS Version:     2.6.31-302-rs
Architecture:   amd64
JVM Version:    1.6.0_16-b01
JVM Vendor:     Sun Microsystems Inc.

Using this method, you can have different Tomcat instances running different versions of Java and control when you want to move between Java versions.

Setup Tomcat2

...

Secure Directory

Finally, because this is a multi-user machine, we secure tomcat from other users and processes. The only users should be serveradmin for read and write and staff for read to debug. All others should not even be able to go into the directory.

Change the permissions,

Code Block
languagexmlbash
cd /opt/
sudo cpchown -a ./apache/tomcat.1/R serveradmin:staff ./apache/0fs-tomcat.2/ # ThisOnly willserveradmin be Tomcat2

Leave Tomcat1 on the ports,

  • 8105 - for shutdown
  • 8109 - for JK Mod
  • 8180 - regular port similar to 80
  • 8543 - ssl port similar to 443

Tomcat2 will use the following ports,

  • 8205 - for shutdown
  • 8209 - for JK Mod
  • 8280 - regular port similar to 80
  • 8643 - ssl port similar to 443

The very first step is to verify that the ports for Tomcat2 are not being used.

Code Block
netstat -an | grep LISTEN | grep 8205
netstat -an | grep LISTEN | grep 8209
netstat -an | grep LISTEN | grep 8280
netstat -an | grep LISTEN | grep 8643

If you get no results then there are no listening ports.

Change Tomcat2 to use use the new ports by editing /opt/tomcat.2/conf/server.xml. Use an editor to search and replace or more quickly using the following sed commands to do modify your file,

Code Block
cd /opt/apache/tomcat.2/conf
sed -i 's/8105/8205/' server.xml
sed -i 's/8109/8209/' server.xml
sed -i 's/8180/8280/' server.xml
sed -i 's/8543/8643/' server.xml

...

and staff can manage files.
sudo chmod o-rwx ./0fs-tomcat/ # Remove "other" from getting any access.
sudo chown -R serveradmin.staff # Ensure new files created follow the Directory's setgid.

However, this is not enough. Any new files created in those directories will change to what the particular user has set in terms of that user's groups. This also includes the process user serveradmin. The log files created when the process starts will belong to serveradmin user and serveradmin group - which we don't want. So to fix this we tell the directory to set the setgid bit,

Code Block
languagebash
cd /opt/
sudo chown -R serveradmin.staff # Ensure new files created follow the Directory's setgid.

Verify Process is Running

Finally startup your Tomcat instances and verify that they are listening,

Code Block
languagebash
su - serveradmin

cd /opt/apache/0fs-tomcat.1/bin/
./startup.sh
cd
/opt/apache/tomcat.2/bin/
./startup.sh

netstat -an | grep LISTEN
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN
tcp6       0      0 127.0.0.1:8105          :::*                    LISTEN
tcp6       0      0 :::81098009                 :::*                    LISTEN
tcp6       0      0 :::81808080                 :::*                    LISTEN
tcp6       0      0 :::80                   :::*                    LISTEN
tcp6       0      0 :::22                   :::*                    LISTEN
unix  2      [ ACC ]     STREAM     LISTENING     7376     @/com/ubuntu/upstart
unix  2      [ ACC ]     STREAM     LISTENING     11434    /var/run/fail2ban/fail2ban.sock
unix  2      [ ACC ]     STREAM     LISTENING     21228    /var/run/apache2/cgisock.4973

Notice that here we have started Tomcat1 Tomcat and it is listening on port 8109 8009 and 81808080.

Tomcat by default will have a sample application installed and running.

Tip

If you have a firewall setup do not forget to open the ports port 8080 for testing and then close them afterwards if you plan to front with the Apache Web Server.

If your server has a web browser you can load the examples page using http://localhost:81808080/examples/. From another computer you can see the examples application by browsing to, http://www.krypton.com:81808080/examples/ where if www.krypton.com is not a real dns, use the server's IP address or add a host file entry to your client system.

Additional Layers

In my experience all my real world systems do not need any more layers to Tomcat. However, there are some odd scenarios which are covered here.

Automatic Startup and Shutdown of Tomcat

I do not recommend setting this up Not recommend until you have proper monitoring in place. If you system reboots you want to know about it.

Even then, most Enterprise simply do not have automatic startup setup. The closest I have personally seen is a delayed startup. The reason being that the appliction server itself may hang the entire machine.

In a Cloud world this is more self-contained so this section will be written out in the future.

Warning

This section is still to be written.

Setup SSL on Tomcat

For testing purposes or if the only thing you want to do is encrypt the channel of communication you can Setup a Self-Signed Certificate for Tomcat.

...

Note

The more enterprise solution is to front Tomcat with Apache and setup SSL on Apache.

UTF-8

Warning

I have only used this in Production with Confluence.

My other i18n projects seem to work fine without this parameter.

More testing and research is needed to determine why and if this is a good idea in general.

If the application written posts with UTF-8 then you need to make sure the connector can handle UTF-8.

...

Make Your Own 0FS TAR Package

Once you are happy with your setup you can make your own package. Using your staff account,

Code Block
languagexmlbash
<Connector port="8180" URIEncoding="UTF-8"/>

If you plan to use mod_jk then also adjust the appropriate connector,

Code Block
languagebash
<Connector port="8109" protocol="AJP/1.3" redirectPort="8643" URIEncoding="UTF-8" />
cd /opt/
sudo tar -czvf 0fs-tomcat.tar.gz ./0fs-tomcat/ # Don't change the parameter orders. 

Notice the use of sudo to run the tar command. This ensures that proper ownership and permissions will carry over to the new system.

Before unpacking to the target system, ensure the users, groups and GUID match following the Bonsai Standards.

References

http://wiki.apache.org/tomcat/FAQ/CharacterEncoding#Q9 - still to finish reading

...