Introduction / FirstSpirit Server configuration / Integration into an external web server / Tomcat servlet engine
Tomcat servlet engine
Table of contents |
In the following configuration, Apache Tomcat can run on the same host or on its own, dedicated host. In order to provide a better load balance with regard to CPU and RAM resources it is suitable to use a dedicated host.
For information on usingn multiple hosts for load balancing see page balancing on multiple servlet engines.
Tomcat can either be run on its own with the HTTP server integrated in Tomcat or it can be enhanced to include the Apache HTTP Server, as described under Apache HTTP Server with the Tomcat servlet engine.
The FirstSpirit configuration must be modified before configuring Tomcat. If Tomcat is not accessible via the same hostname and port as the FirstSpirit server, you must define in the firstspirit5/conf/fs-server.conf file , via which URL the Tomcat should be reachable later on from the clients' point of view, in order to generate a valid URL when sending messages outside of active client connections:
# URL-Parameter for workflow mail
URL=http://fs5server.domain.net:8080
fs.url.hostname=fs5server.domain.net
fs.url.httpport=8080
If HTTPS is used, or if socket mode is to be used instead of the FirstSpirit client HTTP connection mode, refer to the extended parameter for fs.url under server configuration.
In this example, Tomcat, using the “Binary Distribution Core” from http://tomcat.apache.org, is installed under /opt/tomcat.
server.xml
In tomcat/conf/server.xml, set the encoding for the URI parameter to UTF-8, and for existing HTTP and AJP connectors, add the URIEncoding parameter:
<Connector port="8080" protocol="HTTP/1.1" URIEncoding="UTF-8" />
<Connector port="8009" protocol="AJP/1.3" URIEncoding="UTF-8" />
web.xml
In the tomcat/conf/web.xml file, enable checking and compiling of JSP files immediately after each change. To do this, replace the existing lines in the file
<servlet>
<servlet-name>jsp</servlet-name>
<servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
<init-param>
<param-name>fork</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>xpoweredBy</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>3</load-on-startup>
</servlet>
with the following:
<servlet>
<servlet-name>jsp</servlet-name>
<servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
<init-param>
<param-name>fork</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>xpoweredBy</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>development</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>modificationTestInterval</param-name>
<param-value>0</param-value>
</init-param>
<load-on-startup>3</load-on-startup>
</servlet>
If the option of listing the directory contents for the development of web applications in the FirstSpirit server staging area is required, replace lines in the same file
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>listings</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
with the following:
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>listings</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
tomcat-users.xml
To be able to use Tomcat Manager for status monitoring via the URL http://fs5.yourdomain.net:8080/manager/text as an “Admin” user and to automate deployment of web apps via FirstSpirit, add a user account for each Tomcat Manager “manager-gui” and “manager-script” role to the tomcat/conf/tomcat-users.xml file:
<?xml version='1.0' encoding='utf-8'?>
<tomcat-users>
<role rolename="manager-gui"/>
<role rolename="manager-script"/>
<user username="Admin" password="tomcat-password" roles="manager-gui"/>
<user username="fsdeploy" password="deploy-password" roles="manager-script"/>
</tomcat-users>
context.xml
Replace the existing file tomcat/conf/context.xml with the following content to enable careful checking for file changes (HTML). FirstSpirit Server must be accessible from Tomcat within the local network via the host name specified for “firstspirit.host” or the IP address. The “firstspirit.port” entry must match the FirstSpirit server port, as defined in firstspirit5/conf/fs-server.conf by the SOCKET_PORT parameter. In addition, saving persistent session information is disabled because the FirstSpirit web applications do not support this:
<?xml version='1.0' encoding='utf-8'?>
<Context useHttpOnly="true">
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
<!-- disable session persistence across Tomcat restarts --> <Manager pathname="" />
<Resources cachingAllowed="false" />
<Parameter name="firstspirit.host" value="fs5server" override="false" />
<Parameter name="firstspirit.port" value="1088" override="false" />
</Context>
A change must also be made in tomcat/conf/context.xml as described below. Background: When the application server starts up, Tomcat scans all the JAR files of the web apps (fs5root, fs5webedit, etc.) by default to see if it can find certain classes and TLDs. The new parsing behavior leads to significantly longer start-up times. However, these can be reduced by adjusting the JarScanFilter configuration. To improve the start-up times even further, you can also configure Tomcat so that the web apps start up in parallel:
<JarScanner>
<JarScanFilter pluggabilitySkip="${tomcat.util.scan.StandardJarScanFilter.jarsToSkip},
fs-isolated-webrt.jar"
tldSkip="${tomcat.util.scan.StandardJarScanFilter.jarsToSkip},fs-isolated-webrt.jar" />
</JarScanner>
log4j.properties
From FirstSpirit 2022.5 log4j2.xml is to be used. |
Create the file tomcat/lib/log4j.properties with the following content in order to redirect logging of FirstSpirit web applications to a separate log file:
log4j.rootCategory=INFO, fs
# change INFO in the following line to DEBUG
# for detailed FirstSpirit logging:
log4j.logger.de.espirit=INFO
log4j.logger.org.eclipse.jetty=WARN
log4j.logger.org.apache.catalina=INFO
log4j.logger.org.apache.jasper=WARN
log4j.logger.org.apache.log4j.jmx=ERROR
log4j.logger.org.apache.commons.httpclient=INFO
log4j.appender.fs=org.apache.log4j.RollingFileAppender
log4j.appender.fs.File=${catalina.home}/logs/firstspirit.log
log4j.appender.fs.MaxFileSize=10MB
log4j.appender.fs.MaxBackupIndex=9
log4j.appender.fs.layout=org.apache.log4j.PatternLayout
log4j.appender.fs.layout.ConversionPattern=[%d] %t %c %-5p - %m%n
For all web applications for which no Log4j is available (for example modules without corresponding dependence), this configuration is not necessary because Tomcat does not include Log4j implementation. |
Regardless of the selected logging implementation the value for the log level can be customized in the tomcat/conf/catalina.properties file. If you would like to have more extensive log output, you can set the log level for example to sysout.loglevel=INFO.
log4j2.xml
From FirstSpirit 2024.3 the default logging configuration of Tomcat is to be used. |
Create the file tomcat/lib/log4j2.xml with the following content in order to redirect logging of FirstSpirit web applications to a separate log file:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
<Properties>
<Property name="logdir">${sys:catalina.base}/logs</Property>
</Properties>
<Appenders>
<RollingFile name="fs"
fileName="${logdir}/firstspirit.log"
filePattern="${logdir}/firstspirit.log.%i.gz">
<PatternLayout>
<Pattern>[%d] %t %c %-5p - %m%n</Pattern>
</PatternLayout>
<Policies>
<SizeBasedTriggeringPolicy size="1 MB"/>
</Policies>
<DefaultRolloverStrategy max="9"/>
</RollingFile>
</Appenders>
<Loggers>
<!--change INFO in the following line to DEBUG for detailed FirstSpirit logging:-->
<Logger name="de.espirit" level="info" additivity="false">
<AppenderRef ref="fs"/>
</Logger>
<Logger name="org.eclipse.jetty" level="warn" additivity="false">
<AppenderRef ref="fs"/>
</Logger>
<Logger name="org.apache.catalina" level="info" additivity="false">
<AppenderRef ref="fs"/>
</Logger>
<Logger name="org.apache.jasper" level="warn" additivity="false">
<AppenderRef ref="fs"/>
</Logger>
<Logger name="org.apache.commons.httpclient" level="info" additivity="false">
<AppenderRef ref="fs"/>
</Logger>
<Root level="info">
<AppenderRef ref="fs"/>
</Root>
</Loggers>
</Configuration>
For all web applications for which no Log4j is available (for example modules without corresponding dependence), this configuration is not necessary because Tomcat does not include Log4j implementation. |
Regardless of the selected logging implementation the value for the log level can be customized in the tomcat/conf/catalina.properties file. If you would like to have more extensive log output, you can set the log level for example to sysout.loglevel=INFO.
logging.properties
Add the following conftent to the file tomcat/conf/logging.properties in order to redirect logging of FirstSpirit classes and specific web applications to a separate log file:
handlers = 1catalina.org.apache.juli.AsyncFileHandler, 2localhost.org.apache.juli.AsyncFileHandler, 3manager.org.apache.juli.AsyncFileHandler, 4host-manager.org.apache.juli.AsyncFileHandler, 5firstspirit.org.apache.juli.AsyncFileHandler, java.util.logging.ConsoleHandler
.handlers = 1catalina.org.apache.juli.AsyncFileHandler, java.util.logging.ConsoleHandler
[...]
5firstspirit.org.apache.juli.AsyncFileHandler.level = FINE
5firstspirit.org.apache.juli.AsyncFileHandler.directory = ${catalina.base}/logs
5firstspirit.org.apache.juli.AsyncFileHandler.prefix = firstspirit.
5firstspirit.org.apache.juli.AsyncFileHandler.maxDays = 90
5firstspirit.org.apache.juli.AsyncFileHandler.encoding = UTF-8
[...]
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/fs5preview].level = INFO
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/fs5preview].handlers = 5firstspirit.org.apache.juli.AsyncFileHandler
[...]
de.espirit.level = FINE
de.espirit.handlers = 5firstspirit.org.apache.juli.AsyncFileHandler
Regardless of the selected logging implementation the value for the log level can be customized in the tomcat/conf/catalina.properties file. If you would like to have more extensive log output, you can set the log level for example to sysout.loglevel=INFO.
setenv.sh
The Java VM used by Tomcat must meet the configuration requirements for an application server. With Tomcat, the configuration is set using the tomcat/bin/setenv.sh file with the following content, which corresponds to the JVM parameters from firstspirit5/conf/fs-wrapper.conf.
The specifications for the Java heap size (Xmx, Xms) must be adapted according to the available RAM.
The configuration shown below is an example. JVM parameters depend on the JDK being used and Tomcat parameters on the Tomcat version. It is not possible to depict the full range of potential configurations for these third-party components here. Crownpeak recommends optimizing the configuration according to the needs and requirements of productive customer installations, however. Java experts, consultants from partner companies, or Crownpeak Technology GmbH should be consulted for advice in this regard. It is not possible to make universal recommendations. |
Example (configuration of setenv.sh):
# use same umask as given in /opt/firstspirit5/conf/fs-wrapper.isolated.conf
# with parameter wrapper.umask
umask 0027
# use same JVM path as given in /opt/firstspirit5/conf/fs-wrapper.isolated.conf
# with parameter wrapper.java.command
JAVA_HOME="$FS_JAVA_HOME"
# Tomcat Heapsize settings
# set Xmx and Xms to max of 75% of available RAM, max 10000M
# Change jmxremote port to any free availble port
# and consider activiated jmx password security.
CATALINA_OPTS="$CATALINA_OPTS -Xmx4000M"
CATALINA_OPTS="$CATALINA_OPTS -Xms4000M"
CATALINA_OPTS="$CATALINA_OPTS -XX:InitialCodeCacheSize=128M"
CATALINA_OPTS="$CATALINA_OPTS -XX:ReservedCodeCacheSize=128M"
CATALINA_OPTS="$CATALINA_OPTS --add-exports=java.base/sun.security.util=ALL-UNNAMED"
CATALINA_OPTS="$CATALINA_OPTS --add-exports=java.desktop/sun.awt.image=ALL-UNNAMED"
CATALINA_OPTS="$CATALINA_OPTS --illegal-access=permit"
CATALINA_OPTS="$CATALINA_OPTS -XX:+UseCompressedOops"
CATALINA_OPTS="$CATALINA_OPTS -Djava.awt.headless=true"
CATALINA_OPTS="$CATALINA_OPTS -Dfile.encoding=UTF-8"
CATALINA_OPTS="$CATALINA_OPTS -Xshare:off"
CATALINA_OPTS="$CATALINA_OPTS -Djava.net.preferIPv4Stack=true"
CATALINA_OPTS="$CATALINA_OPTS -Djava.io.tmpdir=work"
CATALINA_OPTS="$CATALINA_OPTS -Dcom.sun.management.jmxremote"
CATALINA_OPTS="$CATALINA_OPTS -Dcom.sun.management.jmxremote.ssl=false"
CATALINA_OPTS="$CATALINA_OPTS -Dcom.sun.management.jmxremote.authenticate=false"
CATALINA_OPTS="$CATALINA_OPTS -Dcom.sun.management.jmxremote.port=8006"
CATALINA_OPTS="$CATALINA_OPTS -Xlog:gc*,gc+age=trace,safepoint,heap*,phases*:/opt/tomcat/logs/tomcat-gc.log"
CATALINA_OPTS="$CATALINA_OPTS -Djava.security.auth.login.config=/opt/firstspirit5/conf/fs-jaas.conf"
CATALINA_OPTS="$CATALINA_OPTS -Djava.security.policy=/opt/firstspirit5/conf/fs-server.policy"
CATALINA_PID="/opt/tomcat/work/catalina.pid"
# JPDA configuration
JPDA_OPTS="-agentlib:jdwp=transport=dt_socket,address=127.0.0.1:8002,server=y,suspend=n"
# permanent debugging
#CATALINA_OPTS="$CATALINA_OPTS $JPDA_OPTS"
The parameters -XX:SurvivorRatio=1 and -XX:+NeverTenure should no longer be used from Java 9 onward, as they have negative effects on the system's overall performance. |
The parameter -Xmn should no longer be used from Java 9 onward, as it has negative effects on the G1 garbage collector (Garbage-First). |
For the Apache Tomcat web server, the same --add-opens parameters should be used when operating with Java 17 (or newer) that are stored for FirstSpirit in the firstspirit5/conf/fs-wrapper-vendor.conf file. When using customer-specific modules it may be necessary to define further --add-opens parameters. |
The Java VM manages the Metaspace (another native area of memory in addition to the heap) automatically. Changing the configuration, e.g., using parameter MetaspaceSize or MaxMetaspaceSize, is expressly advised against. |
Start / stop
In the file firstspirit5/tomcat/bin/catalina.sh, change the line
FORCE=0
to
FORCE=1
so that you can define how to shut down Tomcat without “hanging”. If you do not want catalina.sh modified, the parameter “-force” must be added, i.e. “catalina.sh stop -force”, each time Tomcat is stopped.
Tomcat is now started using the following line:
/opt/tomcat/bin/catalina.sh start
To stop:
/opt/tomcat/bin/catalina.sh stop
To launch Tomcat automatically upon system startup, create the file /etc/init.d/tomcat with the following content, define file access rights using chmod a+rx /etc/init.d/tomcat and, depending on the operating system, add the following using the system environment insserv, update-rc.d or chkconfig command:
#!/usr/bin/bash
### BEGIN INIT INFO
# Provides: tomcat
# Required-Start: $local_fs $network
# Should-Start: $netdaemons $named $syslog $remote_fs sendmail
# Required-Stop: $local_fs $network
# Should-Stop: $netdaemons $named $syslog $remote_fs sendmail
# Default-Start: 2 3 5
# Default-Stop: 0 1 6
# Short-Description: FirstSpirit-Tomcat
# Description: FirstSpirit-Tomcat
# chkconfig: 235 95 05
### END INIT INFO
TCUSER=tomcat
TCDIR=/opt/tomcat
case "$1" in
start)
su - $TCUSER -c "$TCDIR/bin/catalina.sh start" \
&& touch /var/lock/subsys/tomcat_$TCUSER
;;
stop)
su - $TCUSER -c "$TCDIR/bin/catalina.sh stop -force" \
&& rm /var/lock/subsys/tomcat_$TCUSER
;;
restart)
$0 stop
$0 start
;;
*)
echo "Usage: $0 { start | stop | restart }"
exit 1
;;
esac
In FirstSpirit ServerManager under server properties, a “Tomcat” web server needs to be added using “PreviewTomcat” as the name, for example (see Adding a Tomcat web server).
Parameters:
- Web server URL: Enter the basis URL of the Tomcat, for example http://tomcat:8080. This URL is required, for instance, to adapt links for FirstSpirit applications on the start page.
- Web directory: leave blank
- Tomcat user: see “username” under the “manager-script” role in the file tomcat/conf/tomcat-users.xml
- Tomcat password: the password associated with the user previously entered, look in the file tomcat/conf/tomcat-users.xml
- Tomcat Manager URLs:
http://tomcathost:8080/manager/text
(Local host name of the Tomcat server, as it is accessed from FirstSpirit Server, as well as Tomcat HTTP Port. If multiple Tomcat instances are set, the URLs are entered with a comma separating them.)
In the server properties, the “PreviewTomcat” must be selected for the FirstSpirit web applications and then installed to the Tomcat server per clicking “Install”. This installation takes place automatically using the script previously registered. The FirstSpirit server will recognize if web applications on a Tomcat running on a dedicated host are not up-to-date and will trigger an update.
If local project web applications are used, they will also have to be installed to “PreviewTomcat”.
Although the web application is present on the external web server once the external web server (in this case: Tomcat) has been configured and installed, the generated FirstSpirit content is not. If the staging area of the FirstSpirit editing system is to be used in the project so that editors can view the generated website by entering the URL http://fshostname.domain/fs5staging into a web browser, please note that further project-specific adjustments are required before the website is deployed to a live web server. Firstly, you must ensure that the external web server has access to the content generated by FirstSpirit. One option (A) is to transfer the generated content onto the external system, e.g. via CRC transfer or rsync. Another option (B) is to configure the settings so that the external system has direct access to the generation directories of the FirstSpirit server, e.g. via nfs-mount. These solutions must be configured on a project-specific basis.