How to Install and Configure Apache Tomcat on Windows Server 2012 R2

Apache Tomcat is the world’s most widely deployed open-source Java web application server, providing a Java Servlet, JavaServer Pages (JSP), and Java EL runtime environment. On Windows Server 2012 R2, Tomcat runs as a Windows service, making it suitable for hosting Java EE web applications in a production environment alongside other Windows Server workloads. This guide covers installing Java, downloading and installing Tomcat, configuring it as a Windows service, setting up the management interface, configuring SSL, deploying a WAR file, and tuning JVM settings for production use.

Prerequisites

  • Windows Server 2012 R2 with administrator access
  • PowerShell 4.0
  • At least 2 GB of RAM available for Tomcat JVM (more for production applications)
  • Java JDK or JRE 11 or later (Java 17 LTS recommended)
  • A WAR file to deploy, or access to the Tomcat Manager web interface

Step 1: Install Java

Install Eclipse Temurin JDK 17 (the recommended open-source JDK) via Chocolatey or manual MSI:

choco install temurin17 -y

# Or via direct MSI download:
Invoke-WebRequest -Uri "https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.11%2B9/OpenJDK17U-jdk_x64_windows_hotspot_17.0.11_9.msi" -OutFile "C:Tempjdk17.msi"
Start-Process msiexec -ArgumentList "/i C:Tempjdk17.msi /quiet ADDLOCAL=FeatureMain" -Wait

Set JAVA_HOME and add to PATH:

$JavaHome = (Get-ChildItem "C:Program FilesEclipse Adoptium" -Directory | Sort-Object Name -Descending | Select-Object -First 1).FullName
[System.Environment]::SetEnvironmentVariable("JAVA_HOME", $JavaHome, "Machine")
$CurrentPath = [System.Environment]::GetEnvironmentVariable("Path","Machine")
[System.Environment]::SetEnvironmentVariable("Path","$CurrentPath;$JavaHomebin","Machine")

# Open new PowerShell and verify
java -version

Step 2: Download Apache Tomcat

Download the Windows 64-bit zip distribution of Tomcat 10.1 (the latest LTS-aligned release). Avoid the installer EXE if you want full control over configuration:

$TomcatVersion = "10.1.25"
$TomcatUrl = "https://dlcdn.apache.org/tomcat/tomcat-10/v${TomcatVersion}/bin/apache-tomcat-${TomcatVersion}-windows-x64.zip"

Invoke-WebRequest -Uri $TomcatUrl -OutFile "C:Temptomcat.zip"

Step 3: Install Tomcat

Extract to a versioned directory for easy upgrades:

New-Item -ItemType Directory -Path "C:Tomcat" -Force
Add-Type -AssemblyName System.IO.Compression.FileSystem
[System.IO.Compression.ZipFile]::ExtractToDirectory("C:Temptomcat.zip","C:Tomcat")

# Rename to a consistent path
$ExtractedDir = Get-ChildItem "C:Tomcat" -Directory | Select-Object -First 1
Rename-Item $ExtractedDir.FullName "C:Tomcattomcat10"

[System.Environment]::SetEnvironmentVariable("CATALINA_HOME","C:Tomcattomcat10","Machine")

Write-Host "Tomcat extracted to C:Tomcattomcat10"

Step 4: Create a Dedicated Service Account

net user tomcat_svc "Tomcat$Svc2024!" /add /comment:"Tomcat Service Account"

# Grant the account access to the Tomcat directory
$acl = Get-Acl "C:Tomcat"
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule("tomcat_svc","FullControl","ContainerInherit,ObjectInherit","None","Allow")
$acl.SetAccessRule($rule)
Set-Acl "C:Tomcat" $acl

Step 5: Install Tomcat as a Windows Service

Use the Tomcat service installer script included in the bin directory:

Set-Location "C:Tomcattomcat10bin"

# Set environment variables needed by the installer
$env:JAVA_HOME    = $JavaHome
$env:CATALINA_HOME = "C:Tomcattomcat10"

# Install as a service
.service.bat install Tomcat10

# Configure service with JVM settings and account
& "C:Tomcattomcat10bintomcat10w.exe" //US//Tomcat10 `
    --Startup=auto `
    --LogPath="C:Tomcattomcat10logs" `
    --ServiceUser=".tomcat_svc" `
    --ServicePassword="Tomcat`$Svc2024!" `
    --JvmMs=512 `
    --JvmMx=2048 `
    --JvmSs=512

Start-Service Tomcat10
Get-Service Tomcat10 | Select-Object Name, Status

Step 6: Open Firewall Rules

New-NetFirewallRule -DisplayName "Tomcat HTTP (8080)"  -Direction Inbound -Protocol TCP -LocalPort 8080  -Action Allow
New-NetFirewallRule -DisplayName "Tomcat HTTPS (8443)" -Direction Inbound -Protocol TCP -LocalPort 8443  -Action Allow
New-NetFirewallRule -DisplayName "Tomcat AJP (8009)"   -Direction Inbound -Protocol TCP -LocalPort 8009  -Action Allow

Step 7: Configure Tomcat Manager Users

Edit the Tomcat user configuration to enable the Manager web application for WAR deployment:

$TomcatUsersXml = @'



  
  
  

  

  

'@

Set-Content -Path "C:Tomcattomcat10conftomcat-users.xml" -Value $TomcatUsersXml -Encoding UTF8

By default, the Manager app restricts access to localhost. For remote management access, modify the context.xml in the Manager application’s META-INF directory to allow access from your management network:

$ManagerContextXml = @'


  
  
  

'@

Set-Content -Path "C:Tomcattomcat10webappsmanagerMETA-INFcontext.xml" -Value $ManagerContextXml -Encoding UTF8

Step 8: Configure JVM Heap and GC Settings

Configure JVM settings for production use. Edit C:Tomcattomcat10binsetenv.bat (create it if it does not exist):

$SetEnvBat = @'
@echo off
set "JAVA_OPTS=-server -Xms512m -Xmx2048m -XX:+UseG1GC -XX:MaxGCPauseMillis=200"
set "JAVA_OPTS=%JAVA_OPTS% -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=C:Tomcattomcat10logsheapdump.hprof"
set "JAVA_OPTS=%JAVA_OPTS% -Djava.awt.headless=true -Dfile.encoding=UTF-8"
set "CATALINA_OUT=C:Tomcattomcat10logscatalina.out"
'@

Set-Content -Path "C:Tomcattomcat10binsetenv.bat" -Value $SetEnvBat -Encoding ASCII

Restart-Service Tomcat10

Step 9: Deploy a WAR File

Deploy a WAR file via the Tomcat Manager REST API:

$WarPath = "C:Appsmyapp.war"
$TomcatUrl = "http://localhost:8080"
$DeployUser = "tomcat-deploy"
$DeployPass = "TomcatDeploy2024!"

# Deploy using the Manager API
$base64auth = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("${DeployUser}:${DeployPass}"))
$headers = @{ Authorization = "Basic $base64auth" }

$deployUrl = "$TomcatUrl/manager/text/deploy?path=/myapp&update=true"
Invoke-RestMethod -Uri $deployUrl -Method PUT -Headers $headers -InFile $WarPath -ContentType "application/octet-stream"

Or simply copy the WAR to the webapps directory for hot deployment:

Copy-Item "C:Buildsmyapp.war" "C:Tomcattomcat10webappsmyapp.war"
# Tomcat automatically deploys it within a few seconds
Start-Sleep -Seconds 10
Invoke-WebRequest -Uri "http://localhost:8080/myapp/" -UseBasicParsing | Select-Object StatusCode

Summary

Apache Tomcat 10.1 is now running as a Windows service on Windows Server 2012 R2 with Java 17, a dedicated low-privilege service account, JVM heap tuning with G1 garbage collector, Manager web application access for remote WAR deployment, and automated application deployment via the REST API. The Tomcat installation supports deploying Java web applications with servlet and JSP support, integrates with CI/CD pipelines through the Manager REST API or WAR file copy deployment, and can be placed behind IIS or an nginx reverse proxy for SSL termination and load balancing in production environments.