Proper Tomcat configuration is essential for running Sakai. This guide covers the required configuration files and settings.
Sakai will not work with default Tomcat settings. You must configure Tomcat according to this guide.
Configuration Overview
Key configuration files:
bin/setenv.sh - JVM memory and options
conf/server.xml - Tomcat server configuration
sakai/sakai.properties - Sakai application settings
JVM Configuration (setenv.sh)
Create $TOMCAT_HOME/bin/setenv.sh with the following settings:
Basic Configuration
export UMASK='0022'
CATALINA_OPTS="-server \
-Djava.awt.headless=true \
-XX:+UseCompressedOops \
-XX:+AlwaysPreTouch \
-XX:+DisableExplicitGC \
-Djava.net.preferIPv4Stack=true"
Memory Settings
Memory settings are critical for Sakai performance. Insufficient memory will cause OutOfMemoryErrors.
# Heap size (adjust based on available RAM)
CATALINA_OPTS="$CATALINA_OPTS -Xms2g -Xmx2g"
# New generation size
CATALINA_OPTS="$CATALINA_OPTS -XX:NewSize=500m -XX:MaxNewSize=500m"
Recommended memory by server size:
- Small (< 100 users):
-Xms2g -Xmx2g
- Medium (100-500 users):
-Xms4g -Xmx4g
- Large (500+ users):
-Xms8g -Xmx8g or higher
Garbage Collector
# G1GC (recommended)
CATALINA_OPTS="$CATALINA_OPTS -XX:+UseG1GC"
Alternative collectors:
# ZGC (Java 17+)
#CATALINA_OPTS="$CATALINA_OPTS -XX:+UseZGC"
# Shenandoah GC
#CATALINA_OPTS="$CATALINA_OPTS -XX:+UseShenandoahGC"
Java Module Options (Java 11+)
Java 11+ requires additional module opens for Sakai to function properly.
JAVA_OPTS="$JAVA_OPTS \
--add-opens=java.base/jdk.internal.access=ALL-UNNAMED \
--add-opens=java.base/jdk.internal.misc=ALL-UNNAMED \
--add-opens=java.base/sun.nio.ch=ALL-UNNAMED \
--add-opens=java.base/sun.util.calendar=ALL-UNNAMED \
--add-opens=java.management/com.sun.jmx.mbeanserver=ALL-UNNAMED \
--add-opens=jdk.internal.jvmstat/sun.jvmstat.monitor=ALL-UNNAMED \
--add-opens=java.base/sun.reflect.generics.reflectiveObjects=ALL-UNNAMED \
--add-opens=jdk.management/com.sun.management.internal=ALL-UNNAMED \
--add-opens=java.base/java.io=ALL-UNNAMED \
--add-opens=java.base/java.nio=ALL-UNNAMED \
--add-opens=java.base/java.net=ALL-UNNAMED \
--add-opens=java.base/java.util=ALL-UNNAMED \
--add-opens=java.base/java.util.concurrent=ALL-UNNAMED \
--add-opens=java.base/java.util.concurrent.locks=ALL-UNNAMED \
--add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED \
--add-opens=java.base/java.lang=ALL-UNNAMED \
--add-opens=java.base/java.lang.invoke=ALL-UNNAMED \
--add-opens=java.base/java.math=ALL-UNNAMED \
--add-opens=java.sql/java.sql=ALL-UNNAMED \
--add-opens=java.base/java.lang.reflect=ALL-UNNAMED \
--add-opens=java.base/java.time=ALL-UNNAMED \
--add-opens=java.base/java.text=ALL-UNNAMED \
--add-opens=java.management/sun.management=ALL-UNNAMED \
--add-opens=java.desktop/java.awt.font=ALL-UNNAMED \
--add-opens=java.desktop/javax.swing.tree=ALL-UNNAMED"
Additional Options
# Jasper configuration
CATALINA_OPTS="$CATALINA_OPTS -Dorg.apache.jasper.compiler.Parser.STRICT_QUOTE_ESCAPING=false"
# HTTP User Agent
CATALINA_OPTS="$CATALINA_OPTS -Dhttp.agent=Sakai"
# Timezone (adjust to your location)
CATALINA_OPTS="$CATALINA_OPTS -Duser.timezone=US/Eastern"
# Cookie name
CATALINA_OPTS="$CATALINA_OPTS -Dsakai.cookieName=SAKAIID"
Demo Mode (Optional)
# Enable demo mode
CATALINA_OPTS="$CATALINA_OPTS -Dsakai.demo=true"
JMX Monitoring (Optional)
# Enable JMX for monitoring
CATALINA_OPTS="$CATALINA_OPTS -Djava.rmi.server.hostname=your.server.ip \
-Dcom.sun.management.jmxremote.port=9999 \
-Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.authenticate=false"
Server Configuration (server.xml)
Update $TOMCAT_HOME/conf/server.xml:
Server Element
<Server port="8005" shutdown="SHUTDOWN" address="0.0.0.0">
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
HTTP Connector
<Connector port="8080"
protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
URIEncoding="UTF-8"
address="0.0.0.0"/>
URIEncoding="UTF-8" is required for proper character encoding in Sakai.
Host Configuration
<Host name="localhost"
startStopThreads="4"
appBase="webapps"
unpackWARs="true"
autoDeploy="true">
<!-- Access logging -->
<Valve className="org.apache.catalina.valves.AccessLogValve"
directory="logs"
prefix="localhost_access_log"
suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
</Host>
SSL/HTTPS Configuration (Optional)
For HTTPS, add an SSL connector:
<Connector port="8443"
protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150"
SSLEnabled="true"
URIEncoding="UTF-8">
<SSLHostConfig>
<Certificate certificateKeystoreFile="conf/keystore.jks"
certificateKeystorePassword="changeit"
type="RSA" />
</SSLHostConfig>
</Connector>
Sakai Configuration (sakai.properties)
Create $TOMCAT_HOME/sakai/sakai.properties:
Database Configuration
# MySQL/MariaDB
vendor@org.sakaiproject.db.api.SqlService=mysql
driverClassName@javax.sql.BaseDataSource=org.mariadb.jdbc.Driver
url@javax.sql.BaseDataSource=jdbc:mariadb://localhost:3306/sakai?useUnicode=true&characterEncoding=UTF-8
hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
validationQuery@javax.sql.BaseDataSource=select 1 from DUAL
defaultTransactionIsolationString@javax.sql.BaseDataSource=TRANSACTION_READ_COMMITTED
# Database credentials
username@javax.sql.BaseDataSource=sakai
password@javax.sql.BaseDataSource=your_password
Server Configuration
# Server URL (change to your domain)
serverUrl=http://localhost:8080
serverName=localhost
# Server ID
serverId=localhost
Email Configuration
# SMTP settings
smtp.enabled=true
smtp.server=smtp.example.com
smtp.port=25
smtp.from[email protected]
# Authentication (if required)
smtp.user=username
smtp.password=password
Upload Limits
# Maximum upload size (in MB)
content.upload.max=100
content.upload.ceiling=1024
Session Timeout
# Session timeout in minutes
inactiveInterval@org.sakaiproject.tool.api.SessionManager=30
Search Configuration
# Enable search
search.enable=true
# Elasticsearch settings (if using)
search.elasticsearch.server=http://localhost:9200
Development Settings
# Show detailed errors (disable in production)
portal.error.showdetail=false
# Log content cleaner errors
content.cleaner.errors.logged=true
Directory Structure
Ensure the following directories exist:
mkdir -p $TOMCAT_HOME/sakai
mkdir -p $TOMCAT_HOME/components
mkdir -p $TOMCAT_HOME/webapps
File Permissions
Set proper permissions:
chmod +x $TOMCAT_HOME/bin/*.sh
chown -R tomcat:tomcat $TOMCAT_HOME
Database Setup
Before starting Tomcat, create the database:
CREATE DATABASE sakai DEFAULT CHARACTER SET utf8mb4;
CREATE USER 'sakai'@'localhost' IDENTIFIED BY 'your_password';
GRANT ALL PRIVILEGES ON sakai.* TO 'sakai'@'localhost';
FLUSH PRIVILEGES;
Use a strong password for the database user in production environments.
JDBC Driver
Download and install the appropriate JDBC driver:
MariaDB/MySQL:
wget https://repo1.maven.org/maven2/org/mariadb/jdbc/mariadb-java-client/3.1.2/mariadb-java-client-3.1.2.jar
cp mariadb-java-client-3.1.2.jar $TOMCAT_HOME/lib/
Starting and Stopping Tomcat
Start Tomcat
cd $TOMCAT_HOME/bin
./startup.sh
With log monitoring:
./startup.sh && tail -f ../logs/catalina.out
Stop Tomcat
cd $TOMCAT_HOME/bin
./shutdown.sh
Force stop if needed:
Logging Configuration
Configure logging in sakai.properties:
# Log configuration
log.config.count=2
log.config.1=INFO.org.hibernate.engine.internal.StatisticalLoggingSessionEventListener
log.config.2=DEBUG.org.hibernate.SQL
# Hibernate logging
hibernate.show_sql=false
hibernate.generate_statistics=false
Production Checklist
Before deploying to production:
Troubleshooting
OutOfMemoryError
Symptom: Tomcat crashes with OutOfMemoryError
Solution: Increase heap size in setenv.sh:
CATALINA_OPTS="$CATALINA_OPTS -Xms4g -Xmx4g"
Symptom: PermGen or Metaspace errors
Solution: Already handled by -XX:+UseCompressedOops and modern GC
Port Already in Use
Symptom: Port 8080 or 8005 already in use
Solution: Change ports in server.xml or stop conflicting service:
lsof -i :8080
kill -9 <PID>
Database Connection Failures
Symptom: Cannot connect to database
Solution: Verify:
- Database is running
- Credentials in
sakai.properties are correct
- JDBC driver is in
$TOMCAT_HOME/lib/
- Network connectivity to database server
Next Steps