Tomcat Installation

We need a Java container to run Jenkins, and we have chosen Tomcat. But you can run it on your preferred Java container.

1. Get Apache Tomcat 8

1.1 Visit Apache Tomcat 8 download page

1.2 Find the latest Apache Tomcat 8 version, and download it using the 32-bit/64-bit Windows Service Installer link to your Downloads folder

2. Install Apache Tomcat 8

2.1 Install the downloaded file, and follow the wizard steps selecting Service Startup on Choose Components steps

2.2 On step Choose Components, select Service Startup

2.3 On step Configuration, set you administrator login

If you don't set the Tomcat Administration Login you won't be able to manage applications from the web interface.

2.4 On step Java Virtual Machine, ensure you are using the JRE version that was installed next to the JDK 8

2.5 Follow all the next steps until installation is completed

3. Define system variables

3.1 Open system properties dialog

3.2 Select Advanced System Settings

3.3 Click on Environment Variables... button

3.4 On the Envirnoment Variable dialog, click on system variables New... button

3.5 Define the CATALINA_HOME variable

3.6 Accept changes and close all dialogs

4. Check the server

4.1 Check on your brower: http://localhost:8080

Instead following the next steps you can install the Apache Tomcat in your Linux distribution. But be aware we have found some distributions in which the Apache Tomcat servers has an overloaded usage of the CPU with no cause. If you detect any problem with your installed distribution, uninstall it and try the manual installation.

1. Get Apache Tomcat 8

1.1 Visit Apache Tomcat 8 download page

1.2 Find the latest Apache Tomcat 8 version, in this example we will get apache-tomcat-8.5.65.tar.gz via wget command to /tmp folder

$ wget -P /tmp http://apache.uvigo.es/tomcat/tomcat-8/v8.5.65/bin/apache-tomcat-8.5.65.tar.gz

2. Extracts to /opt/tomcat8

2.1 Extracts the downloaded file to /opt/tomcat8

$ sudo mkdir /opt/tomcat8

$ sudo tar -xvzf /tmp/apache-tomcat-8.5.65.tar.gz -C /opt/tomcat8
apache-tomcat-8.5.65/conf/
apache-tomcat-8.5.65/conf/catalina.policy
apache-tomcat-8.5.65/conf/catalina.properties
apache-tomcat-8.5.65/conf/context.xml
apache-tomcat-8.5.65/conf/jaspic-providers.xml
apache-tomcat-8.5.65/conf/jaspic-providers.xsd
apache-tomcat-8.5.65/conf/logging.properties
apache-tomcat-8.5.65/conf/server.xml
apache-tomcat-8.5.65/conf/tomcat-users.xml
apache-tomcat-8.5.65/conf/tomcat-users.xsd
apache-tomcat-8.5.65/conf/web.xml
...

$ ls -la /opt/tomcat8
total 12
drwxr-xr-x 3 noroot noroot 4096 Dec 29 15:14 .
drwxr-xr-x 6 root   root   4096 Dec 29 15:14 ..
drwxr-xr-x 8 noroot noroot 4096 Sep 23 01:27 apache-tomcat-8.5.65

3. Define a symbolic link to SonarQube

3.1 For easy upgrades on future it is highly recommended to create the symbolic link

$ sudo ln -s /opt/tomcat8/apache-tomcat-8.5.65 /opt/tomcat8/current

4. Create a Tomcat user

4.1 Create tomcat group

$ sudo groupadd tomcat8

4.2 Create tomcat user and make it a member of the tomcat group, with a home directory of /opt/tomcat/current (where we will install Tomcat), and with a shell of /bin/false (so nobody can log into the account)

$ sudo useradd -s /bin/false -g tomcat8 -d /opt/tomcat8/current tomcat8
$ sudo chown -R tomcat8:tomcat8 /opt/tomcat8

4. Setup as a service with systemctl

This is the recommended way for registering your SonarQube service. If your Linux distribuition does not support systemctl to manage services, then skip to the next point.

4.1 Create the service descriptor

/lib/systemd/system/tomcat8.service
[Unit]
Description=Apache Tomcat8 Web Application Container
After=syslog.target network.target

[Service]
Type=forking

Environment=JAVA_HOME=/opt/java/default-jdk/ PATH=/opt/java/default-jdk/bin:/bin:/usr/bin
Environment=CATALINA_PID=/opt/tomcat8/current/temp/tomcat.pid
Environment=CATALINA_HOME=/opt/tomcat8/current
Environment=CATALINA_BASE=/opt/tomcat8/current
Environment='CATALINA_OPTS=-Xms512M -Xmx1024M -server -XX:+UseParallelGC'
Environment='JAVA_OPTS=-Djava.awt.headless=true -Djava.security.egd=file:/dev/./urandom'

ExecStart=/opt/tomcat8/current/bin/startup.sh
ExecStop=/opt/tomcat8/current/bin/shutdown.sh

User=tomcat8
Group=tomcat8
UMask=0007
RestartSec=10
Restart=always

[Install]
WantedBy=default.target

4.2 Enable the service to start at boot.

$ sudo systemctl enable tomcat8.service

5. Setup as a service with init.d

This setup is an alternative to previous one; if you created your service using systemctl, please skip this chapter

5.1 Create the tomcat8 file with the following standard content:

/etc/init.d/tomcat8
#!/bin/sh
#
# /etc/init.d/tomcat8 -- startup script for the Tomcat 8 servlet engine
#
# Written by Miquel van Smoorenburg <miquels@cistron.nl>.
# Modified for Debian GNU/Linux    by Ian Murdock <imurdock@gnu.ai.mit.edu>.
# Modified for Tomcat by Stefan Gybas <sgybas@debian.org>.
# Modified for Tomcat6 by Thierry Carrez <thierry.carrez@ubuntu.com>.
# Modified for Tomcat7 by Ernesto Hernandez-Novich <emhn@itverx.com.ve>.
# Additional improvements by Jason Brittain <jason.brittain@mulesoft.com>.
#
### BEGIN INIT INFO
# Provides:          tomcat8
# Required-Start:    $local_fs $remote_fs $network
# Required-Stop:     $local_fs $remote_fs $network
# Should-Start:      $named
# Should-Stop:       $named
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start Tomcat.
# Description:       Start the Tomcat servlet engine.
### END INIT INFO

set -e

PATH=/bin:/usr/bin:/sbin:/usr/sbin
NAME=tomcat8
DESC="Tomcat servlet engine"
DEFAULT=/etc/default/$NAME
JVM_TMP=/tmp/tomcat8-$NAME-tmp

if [ `id -u` -ne 0 ]; then
    echo "You need root privileges to run this script"
    exit 1
fi
 
# Make sure tomcat is started with system locale
if [ -r /etc/default/locale ]; then
    . /etc/default/locale
    export LANG
fi

. /lib/lsb/init-functions

if [ -r /etc/default/rcS ]; then
    . /etc/default/rcS
fi


# The following variables can be overwritten in $DEFAULT

# Run Tomcat 8 as this user ID and group ID
TOMCAT8_USER=tomcat8
TOMCAT8_GROUP=tomcat8

# this is a work-around until there is a suitable runtime replacement
# for dpkg-architecture for arch:all packages
# this function sets the variable JDK_DIRS
find_jdks()
{
    for java_version in 9 8 7
    do
        for jvmdir in /usr/lib/jvm/java-${java_version}-openjdk-* \
                      /usr/lib/jvm/jdk-${java_version}-oracle-* \
                      /usr/lib/jvm/jre-${java_version}-oracle-*
        do
            if [ -d "${jvmdir}" ]
            then
                JDK_DIRS="${JDK_DIRS} ${jvmdir}"
            fi
        done
    done

    # Add older non multi arch installations
    JDK_DIRS="${JDK_DIRS} /usr/lib/jvm/java-7-oracle"
}

# The first existing directory is used for JAVA_HOME (if JAVA_HOME is not
# defined in $DEFAULT)
JDK_DIRS="/opt/java/default-jdk"
find_jdks

# Look for the right JVM to use
for jdir in $JDK_DIRS; do
    if [ -r "$jdir/bin/java" -a -z "${JAVA_HOME}" ]; then
    JAVA_HOME="$jdir"
    fi
done
export JAVA_HOME

# Directory where the Tomcat 8 binary distribution resides
CATALINA_HOME=/usr/share/$NAME

# Directory for per-instance configuration files and webapps
CATALINA_BASE=/var/lib/$NAME

# Use the Java security manager? (yes/no)
TOMCAT8_SECURITY=no

# Default Java options
# Set java.awt.headless=true if JAVA_OPTS is not set so the
# Xalan XSL transformer can work without X11 display on JDK 1.4+
# It also looks like the default heap size of 64M is not enough for most cases
# so the maximum heap size is set to 128M
if [ -z "$JAVA_OPTS" ]; then
    JAVA_OPTS="-Djava.awt.headless=true -Xmx128M"
fi

# End of variables that can be overwritten in $DEFAULT

# overwrite settings from default file
if [ -f "$DEFAULT" ]; then
    . "$DEFAULT"
fi

if [ ! -f "$CATALINA_HOME/bin/bootstrap.jar" ]; then
    log_failure_msg "$NAME is not installed"
    exit 1
fi

POLICY_CACHE="$CATALINA_BASE/policy/catalina.policy"

if [ -z "$CATALINA_TMPDIR" ]; then
    CATALINA_TMPDIR="$JVM_TMP"
fi

# Set the JSP compiler if set in the tomcat8.default file
if [ -n "$JSP_COMPILER" ]; then
    JAVA_OPTS="$JAVA_OPTS -Dbuild.compiler=\"$JSP_COMPILER\""
fi

SECURITY=""
if [ "$TOMCAT8_SECURITY" = "yes" ]; then
    SECURITY="-security"
fi

# Define other required variables
CATALINA_PID="/var/run/$NAME.pid"
CATALINA_SH="$CATALINA_HOME/bin/catalina.sh"

# Look for Java Secure Sockets Extension (JSSE) JARs
if [ -z "${JSSE_HOME}" -a -r "${JAVA_HOME}/jre/lib/jsse.jar" ]; then
    JSSE_HOME="${JAVA_HOME}/jre/"
fi

catalina_sh() {
    # Escape any double quotes in the value of JAVA_OPTS
    JAVA_OPTS="$(echo $JAVA_OPTS | sed 's/\"/\\\"/g')"

    AUTHBIND_COMMAND=""
    if [ "$AUTHBIND" = "yes" -a "$1" = "start" ]; then
        AUTHBIND_COMMAND="/usr/bin/authbind --deep /bin/bash -c "
    fi

    # Define the command to run Tomcat's catalina.sh as a daemon
    # set -a tells sh to export assigned variables to spawned shells.
    TOMCAT_SH="set -a; JAVA_HOME=\"$JAVA_HOME\"; source \"$DEFAULT\"; \
        CATALINA_HOME=\"$CATALINA_HOME\"; \
        CATALINA_BASE=\"$CATALINA_BASE\"; \
        JAVA_OPTS=\"$JAVA_OPTS\"; \
        CATALINA_PID=\"$CATALINA_PID\"; \
        CATALINA_TMPDIR=\"$CATALINA_TMPDIR\"; \
        LANG=\"$LANG\"; JSSE_HOME=\"$JSSE_HOME\"; \
        cd \"$CATALINA_BASE\"; \
        \"$CATALINA_SH\" $@"

    if [ "$AUTHBIND" = "yes" -a "$1" = "start" ]; then
        TOMCAT_SH="'$TOMCAT_SH'"
    fi

    # Run the catalina.sh script as a daemon
    set +e
    if [ ! -f "$CATALINA_BASE"/logs/catalina.out ]; then
        # run install as tomcat8 to work around #841371
        su $TOMCAT8_USER -s /bin/bash -c "install -m 644 /dev/null $CATALINA_BASE/logs/catalina.out"
    fi
    install -o $TOMCAT8_USER -g adm -m 644 /dev/null "$CATALINA_PID"
    start-stop-daemon --start -b -u "$TOMCAT8_USER" -g "$TOMCAT8_GROUP" \
        -c "$TOMCAT8_USER" -d "$CATALINA_TMPDIR" -p "$CATALINA_PID" \
        -x /bin/bash -- -c "$AUTHBIND_COMMAND $TOMCAT_SH"
    status="$?"
    set +a -e
    return $status
}

case "$1" in
  start)
    if [ -z "$JAVA_HOME" ]; then
        log_failure_msg "no JDK or JRE found - please set JAVA_HOME"
        exit 1
    fi

    if [ ! -d "$CATALINA_BASE/conf" ]; then
        log_failure_msg "invalid CATALINA_BASE: $CATALINA_BASE"
        exit 1
    fi

    log_daemon_msg "Starting $DESC" "$NAME"
    if start-stop-daemon --test --start --pidfile "$CATALINA_PID" \
        --user $TOMCAT8_USER --exec "$JAVA_HOME/bin/java" \
        >/dev/null; then

        # Regenerate POLICY_CACHE file
        umask 022
        rm -rf "$CATALINA_BASE/policy"
        mkdir "$CATALINA_BASE/policy"
        echo "// AUTO-GENERATED FILE from /etc/tomcat8/policy.d/" \
            > "$POLICY_CACHE"
        echo ""  >> "$POLICY_CACHE"
        cat $CATALINA_BASE/conf/policy.d/*.policy \
            >> "$POLICY_CACHE"

        # Remove / recreate JVM_TMP directory
        rm -rf "$JVM_TMP"
        mkdir "$JVM_TMP" || {
            log_failure_msg "could not create JVM temporary directory"
            exit 1
        }
        chown -h $TOMCAT8_USER "$JVM_TMP"

        catalina_sh start $SECURITY
        sleep 5
            if start-stop-daemon --test --start --pidfile "$CATALINA_PID" \
            --user $TOMCAT8_USER --exec "$JAVA_HOME/bin/java" \
            >/dev/null; then
            if [ -f "$CATALINA_PID" ]; then
                rm -f "$CATALINA_PID"
            fi
            log_end_msg 1
        else
            log_end_msg 0
        fi
    else
            log_progress_msg "(already running)"
        log_end_msg 0
    fi
    ;;
  stop)
    log_daemon_msg "Stopping $DESC" "$NAME"

    set +e
    if [ -f "$CATALINA_PID" ]; then 
        start-stop-daemon --stop --pidfile "$CATALINA_PID" \
            --user "$TOMCAT8_USER" \
            --retry=TERM/20/KILL/5 >/dev/null
        if [ $? -eq 1 ]; then
            log_progress_msg "$DESC is not running but pid file exists, cleaning up"
        elif [ $? -eq 3 ]; then
            PID="`cat $CATALINA_PID`"
            log_failure_msg "Failed to stop $NAME (pid $PID)"
            exit 1
        fi
        rm -f "$CATALINA_PID"
        rm -rf "$JVM_TMP"
    else
        log_progress_msg "(not running)"
    fi
    log_end_msg 0
    set -e
    ;;
   status)
    set +e
    start-stop-daemon --test --start --pidfile "$CATALINA_PID" \
        --user $TOMCAT8_USER --exec "$JAVA_HOME/bin/java" \
        >/dev/null 2>&1
    if [ "$?" = "0" ]; then

        if [ -f "$CATALINA_PID" ]; then
            log_success_msg "$DESC is not running, but pid file exists."
            exit 1
        else
            log_success_msg "$DESC is not running."
            exit 3
        fi
    else
        log_success_msg "$DESC is running with pid `cat $CATALINA_PID`"
    fi
    set -e
        ;;
  restart|force-reload)
    if [ -f "$CATALINA_PID" ]; then
        $0 stop
        sleep 1
    fi
    $0 start
    ;;
  try-restart)
        if start-stop-daemon --test --start --pidfile "$CATALINA_PID" \
        --user $TOMCAT8_USER --exec "$JAVA_HOME/bin/java" \
        >/dev/null; then
        $0 start
    fi
        ;;
  *)
    log_success_msg "Usage: $0 {start|stop|restart|try-restart|force-reload|status}"
    exit 1
    ;;
esac

exit 0

The header of the file is required if you want to avoid the following error when registering the service:

insserv: warning: script 'tomcat8' missing LSB tags and overrides

5.2 Overwrite default tomcat8 configuration

/etc/default/tomcat8
CATALINA_HOME=/opt/tomcat8/current
CATALINA_BASE=/opt/tomcat8/current
JAVA_HOME=/opt/java/default-jdk
JAVA_OPTS="-Djava.awt.headless=true -Xmx512m -XX:+UseConcMarkSweepGC"

5.3 Register the service

$ sudo chmod 755 /etc/init.d/tomcat8
$ sudo update-rc.d -f tomcat8 remove
$ sudo update-rc.d tomcat8 defaults

6. Check the service

6.1 Restart the server to check if the service is loaded automatically on startup

$ service tomcat8 status
● tomcat8.service - Apache Tomcat8 Web Application Container
   Loaded: loaded (/lib/systemd/system/tomcat8.service; enabled)
   Active: active (running) since Mon 2016-10-27 15:06:34 CEST; 45s ago
  Process: 2352 ExecStart=/opt/tomcat/current/bin/startup.sh (code=exited, status=0/SUCCESS)
 Main PID: 2359 (java)
   CGroup: /system.slice/tomcat8.service
           └─2359 /opt/java/default-jdk//bin/java -Djava.util.logging.config.file=/opt/tom...

Sep 27 15:06:34 dev11 systemd[1]: tomcat8.service holdoff time over, scheduling restart.
Sep 27 15:06:34 dev11 systemd[1]: Stopping Apache Tomcat8 Web Application Container...
Sep 27 15:06:34 dev11 systemd[1]: Starting Apache Tomcat8 Web Application Container...
Sep 27 15:06:34 dev11 startup.sh[2352]: Tomcat started.
Sep 27 15:06:34 dev11 systemd[1]: Started Apache Tomcat8 Web Application Container.

6.2 Check on your brower: http://myserver:8080

Remember to configure your firewall to allow port 8080.