When managing Tomcat with Supervisor, we face two critical technical challenges:
- Supervisor's signal-based process termination conflicts with Tomcat's preferred shutdown protocol
- The environment setup complexity when bypassing Tomcat's startup scripts
Tomcat's standard shutdown sequence works through its dedicated shutdown port (default 8005). The shutdown.sh
script essentially sends the SHUTDOWN command to this port, triggering:
- Completion of current requests
- Proper release of resources
- Orderly thread pool termination
Here's an optimal Supervisor configuration that preserves Tomcat's environment while ensuring proper process tracking:
[program:tomcat] command=/path/to/tomcat/bin/catalina.sh run environment=CATALINA_HOME="/path/to/tomcat",JAVA_HOME="/path/to/java" user=tomcat_user autostart=true autorestart=true startsecs=10 startretries=3 redirect_stderr=true stdout_logfile=/var/log/tomcat/stdout.log stopsignal=INT stopwaitsecs=60
For production environments, we recommend combining Supervisor with a custom shutdown script:
- Create a shutdown wrapper script:
#!/bin/bash /path/to/tomcat/bin/shutdown.sh # Wait for clean shutdown sleep 15 # Force kill if still running pkill -INT -f "catalina"
Then configure Supervisor to use this script:
[program:tomcat_shutdown] command=/path/to/shutdown_wrapper.sh autostart=false autorestart=false
For complex deployments, consider these enhancements:
; Additional JVM options in Supervisor config environment=CATALINA_OPTS="-Xms512m -Xmx1024m -Djava.security.egd=file:/dev/./urandom" ; Multiple Tomcat instances [program:tomcat_instance1] command=/path/to/tomcat1/bin/catalina.sh run ... [program:tomcat_instance2] command=/path/to/tomcat2/bin/catalina.sh run ...
Essential commands for managing the setup:
# Check Supervisor status sudo supervisorctl status # Tail Tomcat logs tail -f /var/log/tomcat/stdout.log /path/to/tomcat/logs/catalina.out # Graceful restart sequence sudo supervisorctl stop tomcat sleep 15 sudo supervisorctl start tomcat
For production systems, consider adding these monitoring enhancements:
- Log rotation configuration
- Email alerts for restarts
- Integration with monitoring tools (Prometheus, New Relic)
When managing Tomcat with Supervisor, we face two key technical hurdles:
- Losing Tomcat's native graceful shutdown capability (via shutdown.sh)
- Difficulty maintaining environment variables from startup.sh
While Supervisor doesn't support custom shutdown commands, we can leverage Unix signals. Tomcat responds to SIGTERM for graceful shutdown:
[program:tomcat]
command=/path/to/java -Dcatalina.home=/opt/tomcat ...
stopasgroup=true
killasgroup=true
stopsignal=TERM
Key configuration parameters:
stopasgroup
: Ensures child processes are stoppedkillasgroup
: Sends signal to entire process groupstopsignal
: Uses SIGTERM instead of default SIGQUIT
To maintain the environment setup from startup.sh while still letting Supervisor track the Java process:
[program:tomcat]
command=sh -c '. /path/to/setenv.sh && exec /path/to/java ...'
environment=CATALINA_HOME="/opt/tomcat",JAVA_HOME="/usr/lib/jvm/java-11"
directory=/opt/tomcat
The critical exec
replaces the shell process with Java, allowing proper process tracking.
Here's a production-ready Supervisor config combining both solutions:
[program:tomcat-production]
user=tomcat
command=sh -c '. /opt/tomcat/bin/setenv.sh && exec $JAVA_HOME/bin/java \
-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager \
-Djava.util.logging.config.file=/opt/tomcat/conf/logging.properties \
-Xms512m -Xmx1024m \
-classpath /opt/tomcat/bin/bootstrap.jar:/opt/tomcat/bin/tomcat-juli.jar \
-Dcatalina.base=/opt/tomcat \
-Dcatalina.home=/opt/tomcat \
-Djava.io.tmpdir=/opt/tomcat/temp \
org.apache.catalina.startup.Bootstrap start'
environment=CATALINA_PID="/var/run/tomcat.pid"
directory=/opt/tomcat
autostart=true
autorestart=true
startsecs=30
stopwaitsecs=30
stopasgroup=true
killasgroup=true
stopsignal=TERM
redirect_stderr=true
stdout_logfile=/var/log/tomcat/catalina.out
After implementation, verify proper shutdown behavior:
# Check process tree
ps auxf | grep tomcat
# Test graceful shutdown
supervisorctl stop tomcat-production
# Verify in catalina.out
tail -f /var/log/tomcat/catalina.out
Look for these log entries indicating proper shutdown sequence:
INFO [main] org.apache.catalina.core.StandardServer.await Received shutdown command INFO [Thread-1] org.apache.catalina.core.StandardService.stopInternal Stopping service [Catalina]