- Run tomcat as non-root user for security reasons
- Using official tar.gz file from tomcat.apache.org
- Proper handling of PID files
- No need to modify any of the original Apache-Tomcat scripts
- Save stop of tomcat, even when application shutdown prevents it.
Therefore I've installed tomcat7 myself.
Here we go:
1. Download apache-tomcat-7.0.23.tar.gz
wget http://www.bitlib.net/mirror/apache.org/tomcat/tomcat-7/v7.0.23/bin/apache-tomcat-7.0.23.tar.gz
2. Unpack apache-tomcat-7.0.23.tar.gz
in any directory you like. I use /opt/apache-tomcat_7.0.23 here
cd /opt
tar zxvf ../apache-tomcat-7.0.23.tar.gz
3. Create a tomcat user
useradd -d /usr/share/tomcat -s /sbin/nologin tomcat
4. Create a config directory for the tomcat instance
mkdir /etc/tomcat
5. Create tomcat70.conf file
vi /etc/tomcat/tomcat70.conf
tomcat70.conf content:
# tomcat7.0 service configuration file
# you could also override JAVA_HOME here
# Where your java installation lives
JAVA_HOME="/etc/alternatives/java_sdk" # we use RH/CentOS alternatives aware Jpackage created Java RPM.
##JAVA_HOME="/usr/java/default" # if you use the standard Oracle JDK .bin installer
export JAVA_HOME
# You can pass some parameters to java
# here if you wish to
#JAVA_OPTS="-Xminf0.1 -Xmaxf0.3"
# Use JAVA_OPTS to set java.library.path for libtcnative.so
#JAVA_OPTS="-Djava.library.path=/usr/lib
# Where your tomcat installation lives
CATALINA_HOME="/opt/apache-tomcat_7.0.23"
export CATALINA_HOME
# What user should run tomcat
TOMCAT_USER="tomcat"
# You can change your tomcat locale here
#LANG=en_US
# Time to wait in seconds, before killing process
SHUTDOWN_WAIT=30
# Set the TOMCAT_PID location
CATALINA_PID=/var/run/tomcat70.pid
# If you wish to further customize your tomcat environment,
# put your own definitions here
# (i.e. LD_LIBRARY_PATH for some jdbc drivers)
# Just do not forget to export them :)
# Start HeapSize 512M, Max 1024MB, PermGenSize 512MB
JAVA_OPTS="-Xmx1024M -Xms512M -XX:MaxPermSize=512M"
# AWT Headless Mode and JMX for Lambda-PROBE application
JAVA_OPTS="$JAVA_OPTS -Djava.awt.headless=true"
JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote"
export JAVA_OPTS
This script is based on an old JPackage init.d script for tomcat4 and was heavily modified over time by me - and of course properly supports PID file handling. This is especially needed for tomcat stop in production environment, because sometimes Tomcat is not able to stop when big applications are deployed (e.g. because of Log4J class locking)
/etc/init.d/tomcat70 content:
#!/bin/sh
#
# tomcat70 Startup script for Tomcat 7.0, the Apache Servlet Engine
#
#
# chkconfig: - 80 16
# description: Tomcat 7.0 is the Apache Servlet Engine
# processname: tomcat70
# config: /etc/tomcat/tomcat70.conf
# pidfile: /var/run/tomcat70.pid
#
# Gomez Henri <hgomez@users.sourceforge.net>
# Keith Irwin <keith_irwin@non.hp.com>
# Nicolas Mailhot <nicolas.mailhot@one2team.com>
#
# Adapted and extended for Tomcat6, Tomcat7 default installation on CentOS by Robert Oschwald <robertoschwald@google****.com>
# Note: You must create a config file /etc/tomcat/tomcat70.conf
# version 1.02 - Removed initlog support
# version 1.03 - Removed config:
# version 1.04 - tomcat will start before httpd and stop after httpd
# version 1.05 - jdk hardcoded to link /usr/java/jdk and tomcat runs as "nobody"
# version 1.06 - split up into script and config file
# version 1.07 - Rework from Nicolas ideas
# version 1.08 - Fix work dir permission at start time, switch to use tomcat4
# version 1.09 - Fix pidfile and config tags
# version 1.10 - Fallback to su direct use on systems without Redhat/Mandrake init.d functions
# version 1.11 - Fix webapps dir permissions
# version 1.12 - remove initial start/stop level for chkconfig (- 80 20)
# version 1.13 - remove chown of logs/work/temp/webapps dir, owned by tomcat4 at install time
# version 1.14 - correct the start/stop ugly hack by waiting all the threads stops
# version 1.15 - ensure we're looking for TOMCAT_USER running catalina
# version 1.16 - Add support for CATALINA_PID env var
# version 1.17 - Remove run files only tomcat started correctl
# in start area, check that tomcat is not allready running
# version 1.18 - Fix kill typo (thanks Kaj J. Niemi)
# version 1.19 - Add jar relinking
# version 1.20 - Check there is no stalling tomcat4.pid
# version 1.20tc5 - Changed all instances of tomcat4 to tomcat5 except TOMCAT_USER
# version 1.21 - Add status command
# version 1.21a - Adapted for tomcat55 manual installation, roos
# version 1.21b - tomcat55.conf handling added, roos
# version 1.21b-a - moved tomcat55.conf
# version 1.21b-b - some more changes due to multi-tomcat boot
# version 1.21b-c - tomcat7 handling added, roos
#
# Source function library.
if [ -x /etc/rc.d/init.d/functions ]; then
. /etc/rc.d/init.d/functions
fi
# Get Tomcat config
TOMCAT_CFG="/etc/tomcat/tomcat70.conf"
[ -r "$TOMCAT_CFG" ] && . "${TOMCAT_CFG}"
# if CATALINA_HOME is not set, boil out
if [ -z "$CATALINA_HOME" ]; then
echo "Fatal! CATALINA_HOME not set in tomcat70.conf"
exit 1
fi
# Path to the tomcat launch script (direct don't use wrapper)
TOMCAT_SCRIPT=$CATALINA_HOME/bin/catalina.sh
# by roos, propper umask
umask 002
# Tomcat name :)
TOMCAT_PROG=tomcat70
# if TOMCAT_USER is not set, use tomcat like Apache HTTP server
if [ -z "$TOMCAT_USER" ]; then
TOMCAT_USER="apache"
fi
# Since the daemon function will sandbox $tomcat
# no environment stuff should be defined here anymore.
# Please use the /etc/tomcat/tomcatXX.conf file instead ; it will
# be read by the $tomcat script
RETVAL=0
# added by roos to be able to delete logfiles
umask 002
# See how we were called.
start() {
echo -n "Starting $TOMCAT_PROG: "
if [ -f /var/lock/subsys/tomcat70 ] ; then
if [ -f $CATALINA_PID ]; then
read kpid < $CATALINA_PID
# if checkpid $kpid 2>&1; then
if [ -d "/proc/${kpid}" ]; then
echo "process allready running"
return -1
else
echo "lock file found but no process running for pid $kpid, continuing"
fi
fi
fi
touch $CATALINA_PID
chmod 0777 $CATALINA_PID
chown $TOMCAT_USER $CATALINA_PID
if [ -x /etc/rc.d/init.d/functions ]; then
daemon --user $TOMCAT_USER $TOMCAT_SCRIPT start
else
su - $TOMCAT_USER -c "$TOMCAT_SCRIPT start"
fi
RETVAL=$?
echo
[ $RETVAL = 0 ] && touch /var/lock/subsys/tomcat70
return $RETVAL
}
function stop() {
RETVAL="0"
echo -n "Stopping ${TOMCAT_PROG}: "
if [ -f "/var/lock/subsys/tomcat70" ]; then
if [ -x /etc/rc.d/init.d/functions ]; then
daemon --user $TOMCAT_USER $TOMCAT_SCRIPT stop
else
su - $TOMCAT_USER -c "$TOMCAT_SCRIPT stop"
fi
RETVAL=$?
if [ "$RETVAL" -eq "0" ]; then
count="0"
if [ -f $CATALINA_PID ]; then
read kpid < $CATALINA_PID
if [ -z $kpid ]; then
# already stopped
rm -f /var/lock/subsys/tomcat70 $CATALINA_PID
return $RETVAL
fi
until [ "$(ps --pid $kpid | grep -c $kpid)" -eq "0" ] || \
[ "$count" -gt "$SHUTDOWN_WAIT" ]; do
echo "waiting for processes $kpid to exit"
sleep 1
let count="${count}+1"
done
if [ "$count" -gt "$SHUTDOWN_WAIT" ]; then
echo "killing processes which didn't stop after $SHUTDOWN_WAIT seconds"
kill -9 $kpid
fi
fi
rm -f /var/lock/subsys/tomcat70 $CATALINA_PID
fi
fi
return $RETVAL
}
status() {
if [ -f /var/lock/subsys/tomcat70 ] ; then
if [ -f $CATALINA_PID ]; then
read kpid < $CATALINA_PID
if checkpid $kpid 2>&1; then
echo "tomcat70 is running ($kpid)"
return 0
else
echo "lock file found but no process running for pid $kpid"
fi
fi
fi
echo "tomcat6 is stopped."
return 1
}
# See how we were called.
case "$1" in
start)
start
;;
stop)
stop
;;
status)
status
exit $?
;;
restart)
stop
sleep 2
start
;;
condrestart)
if [ -f $CATALINA_PID ] ; then
stop
start
fi
;;
*)
echo "Usage: $TOMCAT_PROG {start|stop|status|restart|condrestart}"
exit 1
esac
exit $RETVAL
7. set permissions
chmod 755 /etc/init.d/tomcat70
chown -R tomcat /opt/apache-tomcat-7.0.23
chmod -R 775 /opt/apache-tomcat-7.0.23
8. create setenv.sh file
My impression is that this is the most-overseen feature of Apache-Tomcat installation. Many people edit catalina.sh directly to set environment vars like JAVA_HOME.
But there is a standard way to add environment vars by adding a setenv.sh file to the tomcat bin directory without modifying anything in the original files by adding a setenv.sh file to the tomcat bin dir.
/opt/tomcat-7.0.23/bin/setenv.sh content:
# setenv.sh to read env var in catalina.sh
TOMCAT_CFG="/etc/tomcat/tomcat70.conf"
[ -r "$TOMCAT_CFG" ] && . "${TOMCAT_CFG}"
9. Start tomcat
/etc/init.d/tomcat70 start
Hope that helps someone. Any comments appreciated.