How to Install and Configure Tomcat on Windows Server 2022
Apache Tomcat is the standard servlet container for Java web applications. It implements the Jakarta Servlet, Jakarta Server Pages (JSP), and Jakarta WebSocket specifications, making it the deployment target for WAR files built with Spring, Struts, or plain servlets. This guide walks through installing Tomcat on Windows Server 2022, configuring it as a service, deploying applications, integrating with IIS, and tuning the JVM.
Prerequisites: Installing Java
Tomcat requires a Java Runtime Environment (JRE) or Java Development Kit (JDK). For production, use Eclipse Temurin (formerly AdoptOpenJDK), available from adoptium.net. Download the Windows x64 MSI installer for the JDK.
# After JDK installation, verify:
java -version
# Output example:
# openjdk version "21.0.3" 2024-04-16 LTS
# OpenJDK Runtime Environment Temurin-21.0.3+9
# Check JAVA_HOME is set (the Tomcat installer sets it, but verify):
echo %JAVA_HOME%
# Should output: C:Program FilesEclipse Adoptiumjdk-21.0.3.9-hotspot
# If JAVA_HOME is not set, set it:
[System.Environment]::SetEnvironmentVariable("JAVA_HOME", "C:Program FilesEclipse Adoptiumjdk-21.0.3.9-hotspot", "Machine")
# Refresh environment in current shell
$env:JAVA_HOME = "C:Program FilesEclipse Adoptiumjdk-21.0.3.9-hotspot"
Downloading Apache Tomcat
Download the Windows Service Installer (.exe) from tomcat.apache.org. The installer package (e.g., apache-tomcat-10.1.24.exe) installs Tomcat as a Windows service automatically and provides a system tray monitor application. Choose Tomcat 10.x for applications targeting Jakarta EE 10 / Servlet 6.0, or Tomcat 9.x for Java EE 8 / Servlet 4.0 applications.
Alternatively, download the ZIP archive for a manual installation where you control the directory layout:
# Extract ZIP to a standard location
Expand-Archive -Path "apache-tomcat-10.1.24-windows-x64.zip" -DestinationPath "C:Tomcat"
# Resulting layout:
# C:Tomcatapache-tomcat-10.1.24
# bin catalina.bat, startup.bat, shutdown.bat, tomcat10.exe
# conf server.xml, web.xml, context.xml, tomcat-users.xml
# lib servlet-api.jar, JSP/EL libs
# logs catalina.log, localhost_access_log, localhost.log
# webapps ROOT, manager, host-manager
# work compiled JSP cache
# temp
Installing as a Windows Service (Tomcat Installer)
Run the Windows installer as Administrator. The installer provides checkboxes for:
-
Service startup type (Automatic, Manual, Disabled)
-
HTTP port (default 8080)
-
HTTPS port (default 8443)
-
AJP port (default 8009)
-
Administrator username and password for the Manager app
-
JVM path
For a manual ZIP installation, register the service using the tomcat10.exe service wrapper included in the bin directory:
# Open elevated Command Prompt
cd C:Tomcatapache-tomcat-10.1.24bin
# Install as service named "Tomcat10"
service.bat install Tomcat10
# Or using tomcat10.exe directly:
tomcat10.exe //IS//Tomcat10 --DisplayName="Apache Tomcat 10.1" --Install="C:Tomcatapache-tomcat-10.1.24bintomcat10.exe" --LogPath="C:Tomcatapache-tomcat-10.1.24logs" --StdOutput=auto --StdError=auto --Classpath="C:Tomcatapache-tomcat-10.1.24binbootstrap.jar;C:Tomcatapache-tomcat-10.1.24bintomcat-juli.jar" --StartMode=jvm --StartClass=org.apache.catalina.startup.Bootstrap --StartParams=start --StopMode=jvm --StopClass=org.apache.catalina.startup.Bootstrap --StopParams=stop --JvmMs=512 --JvmMx=2048
# Start the service
net start Tomcat10
# Stop the service
net stop Tomcat10
# Verify status
sc query Tomcat10
Configuring server.xml
The primary configuration file is C:Tomcatapache-tomcat-10.1.24confserver.xml. Key sections to understand:
<!--
-->
Change the HTTP connector port by modifying port="8080". After editing server.xml, restart the Tomcat service for changes to take effect.
Deploying WAR Files
The simplest deployment method is dropping a WAR file into the webapps directory. Tomcat’s auto-deployment feature unpacks and starts the application automatically if autoDeploy="true" is set in server.xml:
# Copy WAR file to webapps directory
copy myapp.war C:Tomcatapache-tomcat-10.1.24webapps
# Tomcat will unpack it to:
# C:Tomcatapache-tomcat-10.1.24webappsmyapp
# Access via: http://localhost:8080/myapp/
# To deploy to root context (no path prefix), name the file ROOT.war
copy myapp.war C:Tomcatapache-tomcat-10.1.24webappsROOT.war
# Access via: http://localhost:8080/
# Undeploy by deleting the WAR and the directory
del C:Tomcatapache-tomcat-10.1.24webappsmyapp.war
rmdir /s /q C:Tomcatapache-tomcat-10.1.24webappsmyapp
Tomcat Manager Web Application
The Tomcat Manager app at /manager/html provides a web UI for deploying, undeploying, starting, and stopping applications. It is disabled by default for security. Configure it by editing conftomcat-users.xml:
By default, the Manager app is restricted to localhost. To allow access from other hosts, edit webappsmanagerMETA-INFcontext.xml and modify the Remote Address Filter:
Use the Manager API for scripted deployments from a CI/CD pipeline:
# Deploy a WAR via Manager HTTP API
curl --upload-file myapp.war "http://deployer:DeployPassword!@localhost:8080/manager/text/deploy?path=/myapp&update=true"
# Undeploy
curl "http://deployer:DeployPassword!@localhost:8080/manager/text/undeploy?path=/myapp"
# List all applications
curl "http://deployer:DeployPassword!@localhost:8080/manager/text/list"
Configuring Tomcat with IIS (ARR Proxy)
Rather than exposing Tomcat on port 8080 directly, proxy through IIS using ARR (Application Request Routing). This allows IIS to handle HTTPS, port 80/443 binding, and static file serving while Tomcat handles Java requests.
Install ARR and URL Rewrite on IIS as described in the ARR guide, enable proxy, then create a web.config in your IIS site:
Alternatively, for a more traditional integration, use the mod_jk connector with Apache httpd, or use the AJP connector with IIS and the ISAPI redirector (isapi_redirect.dll). The ARR approach is simpler and recommended for new deployments on Windows Server 2022.
JVM Memory Settings (CATALINA_OPTS)
Tomcat’s JVM memory settings are configured via CATALINA_OPTS or JAVA_OPTS environment variables, or via the Tomcat service wrapper for service installations.
For ZIP installations, create binsetenv.bat:
@echo off
REM setenv.bat — loaded by catalina.bat before starting Tomcat
REM Initial and maximum heap size
set "CATALINA_OPTS=-Xms512m -Xmx2048m"
REM Enable G1 garbage collector (recommended for Java 11+)
set "CATALINA_OPTS=%CATALINA_OPTS% -XX:+UseG1GC"
REM GC logging (Java 11+ syntax)
set "CATALINA_OPTS=%CATALINA_OPTS% -Xlog:gc*:file=C:/Tomcat/logs/gc.log:time,uptime,level,tags:filecount=5,filesize=20m"
REM JVM heap dump on out of memory
set "CATALINA_OPTS=%CATALINA_OPTS% -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=C:/Tomcat/logs/heapdump.hprof"
REM Enable JMX for monitoring (optional)
set "CATALINA_OPTS=%CATALINA_OPTS% -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9090 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false"
For service installations, use the Tomcat Monitor (system tray) or tomcat10w.exe to configure JVM settings via the GUI, or use the service wrapper command line:
# Set JVM memory via tomcat10.exe
tomcat10.exe //US//Tomcat10 --JvmMs=512 --JvmMx=2048
# Verify the settings were applied
tomcat10.exe //PS//Tomcat10
Enabling HTTPS in Tomcat
Configure the HTTPS connector in server.xml using a PKCS12 or JKS keystore. To create a PKCS12 keystore from a PEM certificate:
# Convert PEM certificate and key to PKCS12 keystore (using OpenSSL for Windows or Java keytool)
openssl pkcs12 -export -in cert.pem -inkey privkey.pem -certfile chain.pem -out tomcat.p12 -name tomcat -passout pass:changeit
# Or use Java keytool directly to create a self-signed cert for testing:
keytool -genkey -alias tomcat -keyalg RSA -keysize 2048 -storetype PKCS12 -keystore C:Tomcatconfkeystore.p12 -validity 3650 -storepass changeit -dname "CN=localhost,O=Test,C=US"
Add the HTTPS connector to server.xml:
Logging on Windows (catalina.out Equivalent)
Tomcat on Linux writes to catalina.out. On Windows, logging is split across multiple files in the logs directory:
# Key log files:
# catalina.YYYY-MM-DD.log — Tomcat startup/shutdown messages, unhandled exceptions
# localhost.YYYY-MM-DD.log — Application-level logs for the default virtual host
# localhost_access_log.YYYY-MM-DD.txt — HTTP access log (Apache Combined Log Format)
# manager.YYYY-MM-DD.log — Manager app activity
# Tail the most recent Catalina log (PowerShell)
$today = Get-Date -Format "yyyy-MM-dd"
Get-Content "C:Tomcatapache-tomcat-10.1.24logscatalina.$today.log" -Wait -Tail 50
# Or use a for loop to get the latest log regardless of date
$latest = Get-ChildItem "C:Tomcatapache-tomcat-10.1.24logscatalina.*.log" | Sort-Object LastWriteTime -Descending | Select-Object -First 1
Get-Content $latest.FullName -Wait -Tail 100
Configure logging verbosity in conflogging.properties. To increase logging level for a specific package:
# In conflogging.properties:
# Default is INFO — change to FINE for debugging
org.apache.catalina.level = FINE
org.springframework.level = DEBUG
Tomcat Service Management
# Start Tomcat service
net start Tomcat10
# Stop Tomcat service
net stop Tomcat10
# Restart Tomcat service
net stop Tomcat10 && net start Tomcat10
# Check service status
sc query Tomcat10
# Change startup type to Automatic
sc config Tomcat10 start= auto
# Change startup type to Manual
sc config Tomcat10 start= demand
# View Tomcat service configuration
sc qc Tomcat10
# Delete the service (after stopping it)
sc delete Tomcat10
# Test Tomcat is responding after restart
curl http://localhost:8080/
# Verify open ports
netstat -ano | findstr ":8080"
netstat -ano | findstr ":8443"
Windows Firewall Rules for Tomcat
# Open Tomcat HTTP port (if not behind IIS proxy)
netsh advfirewall firewall add rule name="Tomcat HTTP" protocol=TCP dir=in localport=8080 action=allow
# Open Tomcat HTTPS port
netsh advfirewall firewall add rule name="Tomcat HTTPS" protocol=TCP dir=in localport=8443 action=allow
# If using IIS as front-end proxy, do NOT expose 8080 externally
# Only open IIS ports:
netsh advfirewall firewall add rule name="IIS HTTP" protocol=TCP dir=in localport=80 action=allow
netsh advfirewall firewall add rule name="IIS HTTPS" protocol=TCP dir=in localport=443 action=allow
Apache Tomcat runs reliably on Windows Server 2022 when installed and configured correctly. The Windows Service Installer handles most of the integration work, while server.xml, setenv.bat, and tomcat-users.xml give you full control over connectors, JVM memory, and application security. Combined with IIS ARR as a front-end proxy, you have a production-grade Java application server environment with SSL termination, centralized logging, and Windows service management.