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-NAME cat app/.java-buildpack/tomcat/conf/xxx.xmlAnother 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.
Some related KBs:
How to remotely monitor Java applications deployed on Tanzu Application Service for VMs with Java Management Extensions