The Tomcat container can be customized if you place the custom configuration in a repository. Using an external repository for configuration also facilitates having a single configuration that may be used by a variety of apps.
Here are the steps:
Part 1 builds the repository:
Make a directory to hold the configuration:
mkdir tomcat-config
Make other needed files and directories within the newly created directory:
cd tomcat-config mkdir public mkdir -p tomcat-1.0.0/conf touch Staticfile
Edit Staticfile to contain:
root: public directory: visible
Create a tomcat-1.0.0/conf/context.xml file.
Here is an example (refer https://github.com/cloudfoundry/java-buildpack/tree/main/resources/tomcat/conf):
context.xml
<?xml version='1.0' encoding='utf-8'?> <Context> </Context>
logging.properties:
handlers: org.cloudfoundry.tomcat.logging.CloudFoundryConsoleHandler .handlers: org.cloudfoundry.tomcat.logging.CloudFoundryConsoleHandler org.cloudfoundry.tomcat.logging.CloudFoundryConsoleHandler.level: FINE org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level: INFO org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].level: INFO org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].level: INFO
server.xml:
<?xml version='1.0' encoding='utf-8'?>
<Server port='-1'>
<Service name='Catalina'>
<Connector port='${http.port}' bindOnInit='false' connectionTimeout='20000'>
<UpgradeProtocol className='org.apache.coyote.http2.Http2Protocol' />
</Connector>
<Engine defaultHost='localhost' name='Catalina'>
<Valve className='org.apache.catalina.valves.RemoteIpValve' protocolHeader='x-forwarded-proto'/>
<Valve className='org.cloudfoundry.tomcat.logging.access.CloudFoundryAccessLoggingValve'
pattern='[ACCESS] %{org.apache.catalina.AccessLog.RemoteAddr}r %l %t %D %F %B %S vcap_request_id:%{X-Vcap-Request-Id}i'
enabled='${access.logging.enabled}'/>
<Host name='localhost'
failCtxIfServletStartFails='true'>
<Listener className='org.cloudfoundry.tomcat.lifecycle.ApplicationStartupFailureDetectingLifecycleListener'/>
<Valve className='org.apache.catalina.valves.ErrorReportValve' showReport='false' showServerInfo='false'/>
</Host>
</Engine>
</Service>
</Server>
To customize Tomcat further, users could replace the custom configuration files within the tomcat-1.0.0/conf directory.
Here is an example of server.xml to set threads/process/connections/memory.
<?xml version='1.0' encoding='utf-8'?>
<Server port='-1'>
<Service name='Catalina'>
<Connector port='${http.port}' bindOnInit='false' connectionTimeout='20000'
maxThreads='1000'
minSpareThreads='50'
maxSpareThreads='200'
maxConnections='500'
acceptCount='100'
keepAliveTimeout='5000' >
<UpgradeProtocol className='org.apache.coyote.http2.Http2Protocol' />
</Connector>
<Engine defaultHost='localhost' name='Catalina'>
<Valve className='org.apache.catalina.valves.RemoteIpValve' protocolHeader='x-forwarded-proto'/>
<Valve className='org.cloudfoundry.tomcat.logging.access.CloudFoundryAccessLoggingValve'
pattern='[ACCESS] %{org.apache.catalina.AccessLog.RemoteAddr}r %l %t %D %F %B %S vcap_request_id:%{X-Vcap-Request-Id}i'
enabled='${access.logging.enabled}'/>
<Host name='localhost'
failCtxIfServletStartFails='true'>
<Listener className='org.cloudfoundry.tomcat.lifecycle.ApplicationStartupFailureDetectingLifecycleListener'/>
<Valve className='org.apache.catalina.valves.ErrorReportValve' showReport='false' showServerInfo='false'/>
</Host>
</Engine>
</Service>
<JvmOptions Xmx="1024m" Xms="512m" />
</Server>
Place a compressed TAR format version of the tomcat-1.0.0 directory into the public directory:
tar -czf tomcat-1.0.0.tar.gz tomcat-1.0.0/ cp tomcat-1.0.0.tar.gz public/
With a current working directory of tomcat-config, use cf push to place the configuration into the VMware Tanzu Application Service for VMs space that will host the app:
cf push tomcat-config
Issue the command
cf apps
to acquire the URL of the tomcat-config app. Prepend the listed URL with http:// to have the URL that will identify the location of the configuration needed by the app.
For example, your complete URL will look something like http://tomcat-config.apps.yellow-green.cf-app.com.
Within the tomcat-config directory, edit public/index.yml to have URL-specific contents. Using the example URL as a guide, the contents of this public/index.yml file will contain:
1.0.0: http://tomcat-config.apps.yellow-green.cf-app.com/tomcat-1.0.0.tar.gz
Push the configuration a second time with its completed configuration:
cf push tomcat-config
Part 2 modifies the app to configure the use of the external repository:
Edit the manifest.yml file by appending this URL-specific configuration to the applications section of the manifest.yml file:
env:
JBP_CONFIG_TOMCAT: "{ tomcat: { external_configuration_enabled: true }, external_configuration: { repository_root: "http://tomcat-config.apps.yellow-green.cf-app.com" } }"
Substitute your complete URL for the URL in this example.
A complete manifest.yml file will appear similar to:
---
applications:
- name: http-session-caching
path: build/libs/http-session-caching-0.0.1.war
buildpack: java_buildpack_offline
env:
JBP_CONFIG_TOMCAT: "{ tomcat: { external_configuration_enabled: true }, external_configuration: { repository_root: "http://tomcat-config.apps.yellow-green.cf-app.com" } }"
Push, but do not start, your app:
cf push -f ./manifest.yml --no-start -b BUILDPACK-NAME
where BUILDPACK-NAME is the name you chose for your custom java buildpack, or it is the URL of the most recent Java buildpack version, if you did not create a custom buildpack.
The specification of the buildpack on the cf push command line takes precedence over specification within the manifest.
Bind your app if needed:
cf bind-service APP-NAME SERVICE-INSTANCE-NAME
Start the app
cf start APP-NAME
To verify that the tomcat setting is deactivated for the app, use cf ssh to access the app and visually verify that the settings appear within the xxx.xml file. Use this sequence of commands:
cf ssh APP-NAMEAnother way to check if a custom configuration has been applied, i.e. maxThreads has been applies, is to use JMX. Please refer: How to View Tomcat's Connector Attributes in the Java Buildpack. See screenshot below.
cat app/.java-buildpack/tomcat/conf/xxx.xml
Some related KBs:
How to remotely monitor Java applications deployed on Tanzu Application Service for VMs with Java Management Extensions