title | description | keywords | ms.devlang | ms.topic | ms.date | ms.custom | zone_pivot_groups | adobe-target | author | ms.author |
---|---|---|---|---|---|---|---|---|---|---|
Deploy and Configure Tomcat, JBoss EAP, or Java SE Apps |
Learn how to deploy Tomcat, JBoss EAP, or Java SE apps to run on Azure App Service. Perform common tasks like setting Java versions and configuring logging. |
azure app service, web app, windows, oss, java, tomcat, jboss, spring boot, quarkus |
java |
how-to |
03/27/2025 |
devx-track-java, devx-track-azurecli, devx-track-extended-java, linux-related-content |
app-service-java-hosting |
true |
cephalin |
cephalin |
This article shows you the most common deployment and runtime configuration for Java apps in Azure App Service. If it's your first time using Azure App Service, you should first read through the Java quickstart. You can find the answers to general questions about using App Service that aren't specific to Java development in the App Service FAQ.
[!INCLUDE java-variants]
To show the current Java version, run the following command in Azure Cloud Shell:
az webapp config show --resource-group <resource-group-name> --name <app-name> --query linuxFxVersion
To show all supported Java versions, run the following command in Cloud Shell:
az webapp list-runtimes --os linux | grep "JAVA\|TOMCAT\|JBOSSEAP"
For more detailed version information in the Linux container, open an SSH session with the container. Here are a few examples of what you can run.
::: zone pivot="java-javase,java-tomcat,java-jboss"
To view the Java version in the SSH session:
java -version
::: zone-end
::: zone pivot="java-tomcat"
To view the Tomcat server version in the SSH session:
sh /usr/local/tomcat/version.sh
Or, if your Tomcat server is in a custom location, find version.sh
with:
find / -name "version.sh"
::: zone-end
::: zone pivot="java-jboss"
To view the JBoss EAP server version in the SSH session:
$JBOSS_HOME/bin/jboss-cli.sh --connect --commands=:product-info
::: zone-end
To show the current Java version, run the following command in Azure Cloud Shell:
az webapp config show --name <app-name> --resource-group <resource-group-name> --query "[javaVersion, javaContainer, javaContainerVersion]"
To show all supported Java versions, run the following command in Cloud Shell:
az webapp list-runtimes --os windows | grep java
For more information on version support, see App Service language runtime support policy.
By using the Maven Plugin for Azure Web Apps, you can easily prepare your project with one command in your project root:
mvn com.microsoft.azure:azure-webapp-maven-plugin:2.13.0:config
This command adds an azure-webapp-maven-plugin
plugin and the related configuration by prompting you to select an existing Azure Web App or to create a new one. During configuration, it attempts to detect whether your application should be deployed to Java SE, Tomcat, or (Linux only) JBoss EAP. Then you can deploy your Java app to Azure by using the following command:
mvn package azure-webapp:deploy
Here's a sample configuration in pom.xml
:
<plugin>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-webapp-maven-plugin</artifactId>
<version>2.11.0</version>
<configuration>
<subscriptionId>111111-11111-11111-1111111</subscriptionId>
<resourceGroup>spring-boot-xxxxxxxxxx-rg</resourceGroup>
<appName>spring-boot-xxxxxxxxxx</appName>
<pricingTier>B2</pricingTier>
<region>westus</region>
<runtime>
<os>Linux</os>
<webContainer>Java SE</webContainer>
<javaVersion>Java 17</javaVersion>
</runtime>
<deployment>
<resources>
<resource>
<type>jar</type>
<directory>${project.basedir}/target</directory>
<includes>
<include>*.jar</include>
</includes>
</resource>
</resources>
</deployment>
</configuration>
</plugin>
-
Set up the Gradle Plugin for Azure Web Apps by adding the plugin to
build.gradle
:plugins { id "com.microsoft.azure.azurewebapp" version "1.10.0" }
-
Configure your web app details. The corresponding Azure resources are created if they don't exist. Here's a sample configuration. For details, refer to this document.
azurewebapp { subscription = '<your subscription id>' resourceGroup = '<your resource group>' appName = '<your app name>' pricingTier = '<price tier like 'P1v2'>' region = '<region like 'westus'>' runtime { os = 'Linux' webContainer = 'Tomcat 10.0' // or 'Java SE' if you want to run an executable jar javaVersion = 'Java 17' } appSettings { <key> = <value> } auth { type = 'azure_cli' // support azure_cli, oauth2, device_code and service_principal } }
-
Deploy with one command.
gradle azureWebAppDeploy
Azure provides seamless Java App Service development experience in popular Java Integrated Development Environments (IDEs), including:
- VS Code: Java Web Apps with Visual Studio Code.
- IntelliJ IDEA: Create a Hello World web app for Azure App Service by using IntelliJ.
- Eclipse IDE: Create a Hello World web app for Azure App Service by using Eclipse.
::: zone pivot="java-javase"
To deploy Java Archive (JAR) files to Java SE, use the /api/publish
endpoint of the Kudu site. For more information on this API, see this documentation.
Note
Your JAR application must be named app.jar
for App Service to identify and run your application. The Maven plugin automatically names the application for you during deployment. If you don't wish to rename your JAR to app.jar
, you can upload a shell script with the command to run your JAR app. Paste the absolute path to this script in the Startup File text box in the Configuration section of the portal. The startup script doesn't run from the directory it's in. Therefore, always use absolute paths to reference files in your startup script (for example: java -jar /home/myapp/myapp.jar
).
::: zone-end
::: zone pivot="java-tomcat"
To deploy WAR files to Tomcat, use the /api/wardeploy/
endpoint to POST
your archive file. For more information on this API, see this documentation.
::: zone-end
::: zone pivot="java-jboss"
To deploy WAR files to JBoss EAP, use the /api/wardeploy/
endpoint to POST
your archive file. For more information on this API, see this documentation.
To deploy EAR files, use FTP. Your EAR application is deployed to the context root defined in your application's configuration. For example, if the context root of your app is <context-root>myapp</context-root>
, then you can browse the site at the /myapp
path: http://my-app-name.azurewebsites.net/myapp
. If you want your web app to be served in the root path, ensure that your app sets the context root to the root path: <context-root>/</context-root>
. For more information, see Setting the context root of a web application.
::: zone-end
Don't deploy your WAR or JAR by using FTP. The FTP tool is designed to upload startup scripts, dependencies, or other runtime files. It's not the optimal choice for deploying web apps.
To rewrite or redirect a URL, use one of the available URL rewriters, such as UrlRewriteFilter.
::: zone pivot="java-tomcat"
Tomcat also provides a rewrite valve.
::: zone-end
::: zone pivot="java-jboss"
JBoss EAP also provides a rewrite valve.
::: zone-end
Performance reports, traffic visualizations, and health checkups are available for each app through the Azure portal. For more information, see Azure App Service diagnostics overview.
[!INCLUDE Access diagnostic logs]
[!INCLUDE Access diagnostic logs]
For more information, see Stream logs in Cloud Shell.
[!INCLUDE Open SSH session in browser]
The built-in Java images are based on the Alpine Linux operating system. Use the apk
package manager to install any troubleshooting tools or commands.
All Java runtimes on Azure App Service come with the Java Development Kit (JDK) Flight Recorder for profiling Java workloads. You can use it to record Java Virtual Machine (JVM), system, and application events, and to troubleshoot problems in your applications.
To learn more about the Java profiler, visit the Azure Application Insights documentation.
All Java runtimes on App Service come with the Java Flight Recorder. You can use it to record JVM, system, and application events and to troubleshoot problems in your Java applications.
SSH into App Service and run the jcmd
command to see a list of all the Java processes running. In addition to jcmd
itself, you should see your Java application running with a process ID (PID) number.
078990bbcd11:/home# jcmd
Picked up JAVA_TOOL_OPTIONS: -Djava.net.preferIPv4Stack=true
147 sun.tools.jcmd.JCmd
116 /home/site/wwwroot/app.jar
Execute the following command to start a 30-second recording of the JVM. It profiles the JVM and creates a Java Flight Recorder (JFR) file named jfr_example.jfr
in the home directory. Replace 116
with the PID of your Java app.
jcmd 116 JFR.start name=MyRecording settings=profile duration=30s filename="/home/jfr_example.jfr"
During the 30-second interval, you can validate the recording is taking place by running jcmd 116 JFR.check
. The command shows all recordings for the given Java process.
You can use Java Flight Recorder to continuously profile your Java application with minimal impact on runtime performance. To do so, run the following Azure CLI command to create an app setting named JAVA_OPTS
with the necessary configuration. The contents of the JAVA_OPTS
app setting are passed to the java
command when your app starts.
az webapp config appsettings set -g <your_resource_group> -n <your_app_name> --settings JAVA_OPTS=-XX:StartFlightRecording=disk=true,name=continuous_recording,dumponexit=true,maxsize=1024m,maxage=1d
After the recording starts, you can dump the current recording data at any time by using the JFR.dump
command.
jcmd <pid> JFR.dump name=continuous_recording filename="/home/recording1.jfr"
To take a timed recording, you need the process ID (PID) of the Java application. To find the PID, open a browser to your web app's SCM site at https://<your-site-name>.scm.azurewebsites.net/ProcessExplorer/
. This page shows the running processes in your web app. Find the process named "java" in the table and copy the corresponding PID.
Next, open the Debug Console in the top toolbar of the SCM site and run the following command. Replace <pid>
with the PID you copied earlier. This command starts a 30-second profiler recording of your Java application and generates a file named timed_recording_example.jfr
in the C:\home
directory.
jcmd <pid> JFR.start name=TimedRecording settings=profile duration=30s filename="C:\home\timed_recording_example.JFR"
Use FTPS to download your JFR file to your local machine. To analyze the JFR file, download and install Java Mission Control (JMC). For instructions on how to use Java Mission Control, see the JMC documentation and the installation instructions.
To configure App Service to write your application's standard console output and standard console error streams to the local file system or Azure Blob Storage, do the following. Enable application logging through the Azure portal or in the Azure CLI. If you need longer retention, configure the application to write output to a Blob Storage container.
::: zone pivot="java-javase,java-tomcat"
Your Java and Tomcat app logs can be found in the /home/LogFiles/Application/
directory.
::: zone-end
Azure Blob Storage logging for Linux-based apps can be configured only by using Azure Monitor.
To configure App Service to write your application's standard console output and standard console error streams to the local file system or Azure Blob Storage, do the following. Enable application logging through the Azure portal or in the Azure CLI. Twelve hours after you enable application logging, logging to the local App Service file system instance is disabled. If you need longer retention, configure the application to write output to a Blob Storage container.
::: zone pivot="java-javase,java-tomcat"
Your Java and Tomcat app logs can be found in the /home/LogFiles/Application/
directory.
::: zone-end
If your application uses Logback or Log4j for tracing, you can forward these traces for review into Azure Application Insights. Use the logging framework configuration instructions in Explore Java trace logs in Application Insights.
Note
Due to known vulnerability CVE-2021-44228
, be sure to use Log4j version 2.16 or later.
Azure App Service supports out-of-the-box tuning and customization through the Azure portal and the Azure CLI. Review the following articles for non-Java-specific web app configuration:
- Configure app settings
- Set up a custom domain
- Configure TLS/SSL bindings
- Add a CDN
- Configure the Kudu site
Set the app setting JAVA_COPY_ALL
to true
to copy your app contents to the local worker from the shared file system. This setting helps address file-locking issues.
To set allocated memory or other JVM runtime options, create an app setting named JAVA_OPTS
with the options. App Service passes this setting as an environment variable to the Java runtime when it starts.
::: zone pivot="java-javase,java-jboss"
In the Azure portal, under Application Settings for the web app, create a new app setting named JAVA_OPTS
that includes other settings, such as -Xms512m -Xmx1204m
.
::: zone-end
::: zone pivot="java-tomcat"
In the Azure portal, under Application Settings for the web app, create a new app setting named CATALINA_OPTS
that includes other settings, such as -Xms512m -Xmx1204m
.
::: zone-end
To configure the app setting from the Maven plugin, add setting/value tags in the Azure plugin section. The following example sets a specific minimum and maximum Java heap size:
<appSettings>
<property>
<name>JAVA_OPTS</name>
<value>-Xms1024m -Xmx1024m</value>
</property>
</appSettings>
::: zone pivot="java-tomcat"
Note
You don't need to create a web.config file when using Tomcat on Windows App Service.
::: zone-end
Developers running a single application with one deployment slot in their App Service plan can use the following options:
- B1 and S1 instances:
-Xms1024m -Xmx1024m
- B2 and S2 instances:
-Xms3072m -Xmx3072m
- B3 and S3 instances:
-Xms6144m -Xmx6144m
- P1v2 instances:
-Xms3072m -Xmx3072m
- P2v2 instances:
-Xms6144m -Xmx6144m
- P3v2 instances:
-Xms12800m -Xmx12800m
- P1v3 instances:
-Xms6656m -Xmx6656m
- P2v3 instances:
-Xms14848m -Xmx14848m
- P3v3 instances:
-Xms30720m -Xmx30720m
- I1 instances:
-Xms3072m -Xmx3072m
- I2 instances:
-Xms6144m -Xmx6144m
- I3 instances:
-Xms12800m -Xmx12800m
- I1v2 instances:
-Xms6656m -Xmx6656m
- I2v2 instances:
-Xms14848m -Xmx14848m
- I3v2 instances:
-Xms30720m -Xmx30720m
When tuning application heap settings, review your App Service plan details. Consider the needs of multiple applications and deployment slots to find the optimal allocation of memory.
Turn on support for web sockets in the Azure portal in the Application settings for the application. You need to restart the application for the setting to take effect.
Turn on web socket support by using the Azure CLI with the following command:
az webapp config set --name <app-name> --resource-group <resource-group-name> --web-sockets-enabled true
Then restart your application:
az webapp stop --name <app-name> --resource-group <resource-group-name>
az webapp start --name <app-name> --resource-group <resource-group-name>
In the Azure portal, under Application Settings for the web app, create a new app setting named JAVA_OPTS
with value -Dfile.encoding=UTF-8
.
Alternatively, you can configure the app setting by using the App Service Maven plugin. Add the setting name and value tags in the plugin configuration:
<appSettings>
<property>
<name>JAVA_OPTS</name>
<value>-Dfile.encoding=UTF-8</value>
</property>
</appSettings>
::: zone pivot="java-tomcat"
To improve performance of Tomcat applications, you can compile your JSP files before deploying to App Service. You can use the Maven plugin provided by Apache Sling, or use this Ant build file.
::: zone-end
[!INCLUDE robots933456]
App Service allows users to choose the major version of the JVM, such as Java 8 or Java 11, and the patch version, like 1.8.0_232 or 11.0.5. You can also choose to have the patch version update automatically as new minor versions become available. In most cases, production apps should use pinned patch JVM versions, which prevent unanticipated outages during a patch version autoupdate. All Java web apps use 64-bit JVMs, and it's not configurable.
::: zone pivot="java-tomcat"
If you're using Tomcat, you can choose to pin the patch version of Tomcat. On Windows, you can pin the patch versions of the JVM and Tomcat independently. On Linux, you can pin the patch version of Tomcat. The patch version of the JVM is also pinned but isn't separately configurable.
::: zone-end
If you choose to pin the minor version, you need to periodically update the JVM minor version on the app. To ensure that your application runs on the newer minor version, create a staging slot and increment the minor version on the staging slot. After you confirm that the application runs correctly on the new minor version, you can swap the staging and production slots.
::: zone pivot="java-jboss"
In your JBoss EAP app's SSH session, you can run the JBoss CLI with the following command:
$JBOSS_HOME/bin/jboss-cli.sh --connect
Depending on where JBoss EAP is in the server lifecycle, you might not be able to connect. Wait a few minutes and try again. This approach is useful for quick checks of your current server state (for example, to see if a data source is properly configured).
Also, changes you make to the server with the JBoss CLI in the SSH session don't persist after the app restarts. Each time the app starts, the JBoss EAP server begins with a clean installation. During the startup lifecycle, App Service makes the necessary server configurations and deploys the app. To make any persistent changes in the JBoss EAP server, use a custom startup script or a startup command. For an end-to-end example, see Configure data sources for a Java SE, Tomcat, or JBoss EAP app in Azure App Service.
Alternatively, you can manually configure App Service to run any file on startup. For example:
az webapp config set --resource-group <group-name> --name <app-name> --startup-file /home/site/scripts/foo.sh
For more information about the CLI commands that you can run, see:
App Service supports clustering for JBoss EAP versions 7.4.1 and greater. To enable clustering, your web app must be integrated with a virtual network. When the web app is integrated with a virtual network, it restarts, and the JBoss EAP installation automatically starts up with a clustered configuration. When you run multiple instances with autoscaling, the JBoss EAP instances communicate with each other over the subnet specified in the virtual network integration. You can disable clustering by creating an app setting named WEBSITE_DISABLE_CLUSTERING
with any value.
:::image type="content" source="media/configure-language-java-deploy-run/jboss-clustering.png" alt-text="A diagram that shows a virtual network-integrated JBoss EAP App Service app, scaled out to three instances.":::
Note
If you're enabling your virtual network integration with an ARM template, you need to manually set the property vnetPrivatePorts
to a value of 2
. If you enable virtual network integration from the CLI or portal, this property is set for you automatically.
When clustering is enabled, the JBoss EAP instances use the FILE_PING
JGroups discovery protocol to discover new instances and persist cluster information (for example: the cluster members, their identifiers, and their IP addresses). On App Service, these files are under /home/clusterinfo/
. The first EAP instance to start obtains read/write permissions on the cluster membership file. Other instances read the file, find the primary node, and coordinate with that node to be included in the cluster and added to the file.
Note
You can avoid JBoss EAP clustering timeouts by cleaning up obsolete discovery files during your app startup.
The Premium V3 and Isolated V2 App Service Plan types can optionally be distributed across availability zones to improve resiliency and reliability for your business-critical workloads. This architecture is also known as zone redundancy. The JBoss EAP clustering feature is compatible with the zone redundancy feature.
When you're configuring autoscale rules for horizontal scaling, it's important to remove instances incrementally (one at a time) to ensure that each removed instance can transfer its activity (such as handling a database transaction) to another member of the cluster. When you're configuring your autoscale rules in the portal to scale down, use the following options:
- Operation: "Decrease count by"
- Cool down: "5 minutes" or greater
- Instance count: 1
You don't need to incrementally add instances (scaling out). You can add multiple instances to the cluster at a time.
JBoss EAP is available in the following pricing tiers: F1, P0v3, P1mv3, P2mv3, P3mv3, P4mv3, and P5mv3.
A JBoss EAP app in App Service goes through five distinct phases before launching the server:
- Environment setup phase
- Server launch phase
- Server configuration phase
- App deployment phase
- Server reload phase
See the following sections for details and opportunities to customize (such as through app settings).
- The SSH service is started to enable secure SSH sessions with the container.
- The Java runtime keystore is updated with any public and private certificates that are defined in the Azure portal.
- Public certificates are provided by the platform in the
/var/ssl/certs
directory, and they're loaded to$JRE_HOME/lib/security/cacerts
. - Private certificates are provided by the platform in the
/var/ssl/private
directory, and they're loaded to$JRE_HOME/lib/security/client.jks
.
- Public certificates are provided by the platform in the
- If any certificates are loaded in the Java keystore in this step, the properties
javax.net.ssl.keyStore
,javax.net.ssl.keyStorePassword
, andjavax.net.ssl.keyStoreType
are added to theJAVA_OPTS
environment variable. - Some initial JVM configuration is determined, like logging directories and Java memory heap parameters:
- If you provide the
–Xms
or–Xmx
flags for memory in the app settingJAVA_OPTS
, these values override the ones provided by the platform. - If you configure the app setting
WEBSITES_CONTAINER_STOP_TIME_LIMIT
, the value is passed to the runtime propertyorg.wildfly.sigterm.suspend.timeout
, which controls the maximum shutdown wait time (in seconds) when JBoss EAP is being stopped.
- If you provide the
- If the app is integrated with a virtual network, the App Service runtime passes a list of ports to be used for inter-server communication in the environment variable
WEBSITE_PRIVATE_PORTS
and launches JBoss EAP by using theclustering
configuration. Otherwise, thestandalone
configuration is used.- For the
clustering
configuration, the server configuration filestandalone-azure-full-ha.xml
is used. - For the
standalone
configuration, the server configuration filestandalone-full.xml
is used.
- For the
- If JBoss EAP is launched in the
clustering
configuration:- Each JBoss EAP instance receives an internal identifier between 0 and the number of instances that the app is scaled out to.
- If some files are found in the transaction store path for this server instance (by using its internal identifier), it means this server instance is taking the place of an identical service instance. The other service instance previously crashed and left uncommitted transactions behind. The server is configured to resume the work on these transactions.
- Regardless of whether JBoss EAP starts in the
clustering
orstandalone
configuration, if the server version is 7.4 or later and the runtime uses Java 17, then the configuration is updated to enable the Elytron subsystem for security. - If you configure the app setting
WEBSITE_JBOSS_OPTS
, the value is passed to the JBoss launcher script. This setting can be used to provide paths to property files and more flags that influence the startup of JBoss EAP.
-
At the start of this phase, App Service first waits for both the JBoss EAP server and the admin interface to be ready to receive requests before continuing. This process can take a few more seconds if Application Insights is enabled.
-
When both JBoss EAP Server and the admin interface are ready, App Service takes the following actions:
- Adds the JBoss EAP module
azure.appservice
, which provides utility classes for logging and integration with App Service. - Updates the console logger to use a colorless mode so that log files aren't full of color-escaping sequences.
- Sets up the integration with Azure Monitor logs.
- Updates the binding IP addresses of the Web Services Description Language (WSDL) and management interfaces.
- Adds the JBoss EAP module
azure.appservice.easyauth
for integration with App Service authentication and Microsoft Entra ID. - Updates the logging configuration of access logs and the name and rotation of the main server log file.
- Adds the JBoss EAP module
-
Unless the app setting
WEBSITE_SKIP_AUTOCONFIGURE_DATABASE
is defined, App Service autodetects Java Database Connectivity (JDBC) URLs in the App Service app settings. If valid JDBC URLs exist for PostgreSQL, MySQL, MariaDB, Oracle, SQL Server, or Azure SQL Database, it adds the corresponding drivers to the server, adds a data source for each of the JDBC URLs, and sets the Java Naming and Directory Interface (JNDI) name for each data source tojava:jboss/env/jdbc/<app-setting-name>_DS
, where<app-setting-name>
is the name of the app setting. -
If the
clustering
configuration is enabled, the console logger to be configured is checked. -
If there are JAR files deployed to the
/home/site/libs
directory, a new global module is created with all of these JAR files. -
At the end of the phase, App Service runs the custom startup script, if one exists. The search logic for the custom startup script is defined as follows:
- If you configured a startup command (for example, through the Azure portal or the Azure CLI), run it; otherwise,
- If the path
/home/site/scripts/startup.sh
exists, use it; otherwise, - If the path
/home/startup.sh
exists, use it.
The custom startup command or script runs as the root user (no need for sudo
), so they can install Linux packages or launch the JBoss CLI to perform more JBoss EAP install/customization commands like creating data sources and installing resource adapters. For information on Ubuntu package management commands, see the Ubuntu Server documentation. For JBoss CLI commands, see the JBoss Management CLI Guide.
The startup script deploys apps to JBoss EAP by looking in the following locations, in order of precedence:
- If you configured the app setting
WEBSITE_JAVA_WAR_FILE_NAME
, deploy the file designated by it. - If
/home/site/wwwroot/app.war
exists, deploy it. - If any other EAR and WAR files exist in
/home/site/wwwroot
, deploy them. - If
/home/site/wwwroot/webapps
exists, deploy the files and directories in it. WAR files are deployed as applications themselves, and directories are deployed as "exploded" (uncompressed) web apps. - If any standalone JSP pages exist in
/home/site/wwwroot
, copy them to the web server root and deploy them as one web app. - If no deployable files are found, deploy the default welcome page (parking page) in the root context.
- After the deployment steps are complete, the JBoss EAP server is reloaded to apply any changes that require a server reload.
- After the server reloads, the applications deployed to the JBoss EAP server should be ready to respond to requests.
- The server runs until the App Service app is stopped or restarted. You can manually stop or restart the App Service app, or you trigger a restart when you deploy files or make configuration changes to the App Service app.
- If the JBoss EAP server exits abnormally in the
clustering
configuration, a final function calledemit_alert_tx_store_not_empty
is executed. The function checks if the JBoss EAP process left a nonempty transaction store file in disk. If so, an error is logged in the console:Error: finishing server with non-empty store for node XXXX
. When a new server instance is started, it looks for these nonempty transaction store files to resume the work (see 2. Server launch phase).
::: zone-end
::: zone pivot="java-tomcat"
Note
This section applies to Linux only.
Java developers can customize the server settings, troubleshoot issues, and deploy applications to Tomcat with confidence if they know about the server.xml file and configuration details of Tomcat. Possible customizations include:
- Customizing Tomcat configuration: When you understand the server.xml file and Tomcat's configuration details, you can fine-tune the server settings to match the needs of their applications.
- Debugging: When an application is deployed on a Tomcat server, developers need to know the server configuration to debug any issues that might arise. This process includes checking the server logs, examining the configuration files, and identifying any errors that might be occurring.
- Troubleshooting Tomcat issues: Inevitably, Java developers encounter issues with their Tomcat server, such as performance problems or configuration errors. When you understand the server.xml file and Tomcat's configuration details, developers can quickly diagnose and troubleshoot these issues, which can save time and effort.
- Deploying applications to Tomcat: To deploy a Java web application to Tomcat, developers need to know how to configure the server.xml file and other Tomcat settings. You need to understand these details to deploy applications successfully and ensure that they run smoothly on the server.
When you create an app with built-in Tomcat to host your Java workload (a WAR file or a JAR file), there are certain settings that you get out of the box for Tomcat configuration. You can refer to the official Apache Tomcat documentation for detailed information, including the default configuration for Tomcat Web Server.
Additionally, there are certain transformations that are applied on top of the server.xml for Tomcat distribution upon start. These transformations include changes to the Connector, Host, and Valve settings.
The latest versions of Tomcat have server.xml (8.5.58 and 9.0.38 onward). Older versions of Tomcat don't use transforms and might have different behavior as a result.
<Connector port="${port.http}" address="127.0.0.1" maxHttpHeaderSize="16384" compression="on" URIEncoding="UTF-8" connectionTimeout="${site.connectionTimeout}" maxThreads="${catalina.maxThreads}" maxConnections="${catalina.maxConnections}" protocol="HTTP/1.1" redirectPort="8443"/>
maxHttpHeaderSize
is set to16384
.URIEncoding
is set toUTF-8
.connectionTimeout
is set toWEBSITE_TOMCAT_CONNECTION_TIMEOUT
, which defaults to240000
.maxThreads
is set toWEBSITE_CATALINA_MAXTHREADS
, which defaults to200
.maxConnections
is set toWEBSITE_CATALINA_MAXCONNECTIONS
, which defaults to10000
.
Note
The connectionTimeout
, maxThreads
, and maxConnections
settings can be tuned with app settings.
Following are example CLI commands that you might use to alter the values of connectionTimeout
, maxThreads
, or maxConnections
:
az webapp config appsettings set --resource-group myResourceGroup --name myApp --settings WEBSITE_TOMCAT_CONNECTION_TIMEOUT=120000
az webapp config appsettings set --resource-group myResourceGroup --name myApp --settings WEBSITE_CATALINA_MAXTHREADS=100
az webapp config appsettings set --resource-group myResourceGroup --name myApp --settings WEBSITE_CATALINA_MAXCONNECTIONS=5000
Connector uses the address of the container instead of 127.0.0.1.
<Host appBase="${site.appbase}" xmlBase="${site.xmlbase}" unpackWARs="${site.unpackwars}" workDir="${site.tempdir}" errorReportValveClass="com.microsoft.azure.appservice.AppServiceErrorReportValve" name="localhost" autoDeploy="true">
appBase
is set toAZURE_SITE_APP_BASE
, which defaults to localWebappsLocalPath
.xmlBase
is set toAZURE_SITE_HOME
, which defaults to/site/wwwroot
.unpackWARs
is set toAZURE_UNPACK_WARS
, which defaults totrue
.workDir
is set toJAVA_TMP_DIR
, which defaultsTMP
.errorReportValveClass
uses our custom error report valve.
<Valve prefix="site_access_log.${catalina.instance.name}" pattern="%h %l %u %t "%r" %s %b %D %{x-arr-log-id}i" directory="${site.logdir}/http/RawLogs" maxDays="${site.logRetentionDays}" className="org.apache.catalina.valves.AccessLogValve" suffix=".txt"/>
directory
is set toAZURE_LOGGING_DIR
, which defaults tohome\logFiles
.maxDays
is set toWEBSITE_HTTPLOGGING_RETENTION_DAYS
, which defaults to7
. This value aligns with the application-logging platform default.
On Linux, it has all of the same customization, and it adds some error and reporting pages to the valve:
<xsl:attribute name="appServiceErrorPage">
<xsl:value-of select="'${appService.valves.appServiceErrorPage}'"/>
</xsl:attribute>
<xsl:attribute name="showReport">
<xsl:value-of select="'${catalina.valves.showReport}'"/>
</xsl:attribute>
<xsl:attribute name="showServerInfo">
<xsl:value-of select="'${catalina.valves.showServerInfo}'"/>
</xsl:attribute>
::: zone-end
Visit the Azure for Java Developers center to find Azure quickstarts, tutorials, and Java reference documentation.