Installing Tomcat

Introduction

Before you deploy a WAR or edit server.xml, you need a working standalone Tomcat on your machine. This chapter installs Apache Tomcat 10.1.x (Jakarta Servlet, jakarta.*), verifies JDK 17+, starts the server, and confirms the default welcome page at http://127.0.0.1:8080/. A brief directory map is included here; Tomcat Directory Layout goes deeper in the next chapter.

Prerequisites

  • What Is Tomcat
  • JDK 17 or 21 installed and on PATH — see Installing Java for Spring Boot if needed
  • Administrator rights (Windows) or sudo (Linux) for install paths and ports
  • ~150 MB disk for Tomcat; more for deployed apps and logs

Version and JDK Matrix

TomcatServlet APIRecommended JDKHello Code default
10.1.xJakarta (jakarta.*)17 or 21Yes
9.0.xJava EE (javax.*)8+Legacy apps only

This track uses Tomcat 10.1.x to align with Spring Boot 3.

Verify Java First

Tomcat is a Java program—it will not start without a valid JDK.

bash
java -version
echo $JAVA_HOME    # macOS/Linux
echo %JAVA_HOME%   # Windows CMD

Code explanation:

  • Output should show 17 or 21 (not an ancient JRE-only install)
  • JAVA_HOME should point to the JDK root (folder containing bin/java), not bin itself

Warning

Wrong Java on PATH

If java -version shows an old version while IDEA uses 21, Tomcat may fail with version errors. Fix PATH and JAVA_HOME, then open a new terminal.

Choose Your Install Method

MethodBest forPaths
Official zip/tar.gz (recommended)Learning, full control, matches docsYou pick (e.g. C:\apache-tomcat-10.1.x, /opt/tomcat)
OS package (apt, dnf, Homebrew)Quick system serviceDistro-specific (/usr/share/tomcat*, /etc/tomcat*)
DockerIsolated experiments, CI/usr/local/tomcat/ inside container

Examples below use the official binary unless noted. Package paths differ—always run catalina.sh version or check your distro docs after install.

Download Tomcat 10.1

  1. Open Apache Tomcat 10 downloads
  2. Under Core, download:
    • Windows: 64-bit Windows zip (e.g. apache-tomcat-10.1.xx-windows-x64.zip)
    • macOS / Linux: tar.gz (e.g. apache-tomcat-10.1.xx.tar.gz)

Verify the archive checksum on the download page when you want extra assurance (optional for local learning).

Install on Windows

  1. Unzip to a short path without spaces or non-ASCII characters, for example:
text
C:\apache-tomcat-10.1.34
  1. Optional but recommended—set environment variables (System Properties → Environment Variables):
VariableExample value
JAVA_HOMEC:\Program Files\Eclipse Adoptium\jdk-21.x.x
CATALINA_HOMEC:\apache-tomcat-10.1.34
  1. Do not add Tomcat bin to PATH until you are comfortable—use full paths or cd into bin first.

Start Tomcat from PowerShell or CMD:

bat
cd C:\apache-tomcat-10.1.34\bin
startup.bat

Stop:

bat
shutdown.bat

Code explanation:

  • startup.bat launches Tomcat in a separate console window by default
  • A new window shows log lines ending with Server startup in … ms
  • Default HTTP port is 8080

Tip

Run in Foreground for Learning

Use catalina.bat run in bin/ to keep logs in the current terminal—easier for debugging. Covered in more detail in Start, Stop, and Environment.

Install on macOS

bash
cd ~/tools
curl -O https://dlcdn.apache.org/tomcat/tomcat-10/v10.1.34/bin/apache-tomcat-10.1.34.tar.gz
tar xzf apache-tomcat-10.1.34.tar.gz
export CATALINA_HOME=$HOME/tools/apache-tomcat-10.1.34
export JAVA_HOME=$(/usr/libexec/java_home -v 21)

Add to ~/.zshrc or ~/.bash_profile:

bash
export JAVA_HOME=$(/usr/libexec/java_home -v 21)
export CATALINA_HOME=$HOME/tools/apache-tomcat-10.1.34

Start and stop:

bash
$CATALINA_HOME/bin/startup.sh
$CATALINA_HOME/bin/shutdown.sh

Option B: Homebrew

bash
brew install tomcat
brew services start tomcat

Code explanation:

  • Homebrew installs to a cellar path and may use different layout than the official zip
  • For tutorials that reference CATALINA_HOME/webapps/, prefer Option A unless you map Brew paths deliberately

Install on Linux (Ubuntu / Debian)

bash
sudo mkdir -p /opt
cd /tmp
curl -O https://dlcdn.apache.org/tomcat/tomcat-10/v10.1.34/bin/apache-tomcat-10.1.34.tar.gz
sudo tar xzf apache-tomcat-10.1.34.tar.gz -C /opt
sudo ln -s /opt/apache-tomcat-10.1.34 /opt/tomcat

Create a dedicated user (production habit; good practice even when learning):

bash
sudo useradd -r -m -U -d /opt/tomcat -s /bin/false tomcat || true
sudo chown -R tomcat:tomcat /opt/apache-tomcat-10.1.34

Run as your own user for local learning (skip chown if only you use the machine):

bash
export CATALINA_HOME=/opt/tomcat
export JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64   # adjust if needed
/opt/tomcat/bin/startup.sh

Option B: APT package

bash
sudo apt update
sudo apt install -y tomcat10 tomcat10-admin
sudo systemctl enable tomcat10
sudo systemctl start tomcat10

Typical paths on Debian/Ubuntu:

PathPurpose
/usr/share/tomcat10/Installation root (often CATALINA_HOME)
/etc/tomcat10/Config overlays
/var/lib/tomcat10/webapps/Deployed applications
/var/log/tomcat10/Logs

Code explanation:

  • Package layout splits config and webapps from the upstream tar.gz tree
  • Official /opt/tomcat examples in later chapters map cleanly to Option A

On Rocky / Alma / Fedora:

bash
sudo dnf install -y tomcat tomcat-webapps
sudo systemctl enable --now tomcat

Install with Docker (optional)

Quick smoke test without touching the host filesystem:

bash
docker run -d --name tomcat -p 8080:8080 tomcat:10.1-jdk21
curl -I http://127.0.0.1:8080/

Code explanation:

  • tomcat:10.1-jdk21 — Tomcat 10.1 with JDK 21 inside the image
  • -p 8080:8080 — maps container port 8080 to your host
  • WAR deploy and config mounts are covered in Tomcat and Docker

Stop and remove:

bash
docker stop tomcat && docker rm tomcat

Verify Tomcat Is Running

HTTP check

bash
curl -I http://127.0.0.1:8080/

Expected: HTTP/1.1 200 and a Server: Apache-Coyote/1.1 or similar header.

Fetch the page title:

bash
curl -s http://127.0.0.1:8080/ | head -5

You should see Apache Tomcat welcome HTML.

Browser

Open:

text
http://127.0.0.1:8080/
http://localhost:8080/

On a remote VPS, use the public IP only if port 8080 is open in the firewall—production usually keeps Tomcat on localhost and uses Nginx on 80/443.

Version command

From bin/:

bash
./catalina.sh version    # Linux/macOS
catalina.bat version     # Windows

Shows Tomcat version, JVM version, and JAVA_HOME Tomcat detected.

Quick Directory Map (Official Install)

After unzipping, your tree looks like this:

text
apache-tomcat-10.1.x/
├── bin/          startup.sh, shutdown.sh, catalina.sh
├── conf/         server.xml, web.xml, tomcat-users.xml
├── lib/          Tomcat-wide JARs
├── logs/         catalina.*.log, localhost.*.log
├── webapps/      Deploy WARs here (default)
├── work/         JSP compile cache (auto-created)
├── temp/         Temporary files
└── RUNNING.txt   Quick start notes from Apache
PathPurpose
bin/Start/stop scripts and launchers
conf/Main configuration—backup before editing
webapps/Each folder or .war becomes a web application
logs/First place to look when startup fails

Tip

Backup Before Editing conf/

bash
cp conf/server.xml conf/server.xml.bak

Full explanation of CATALINA_HOME, CATALINA_BASE, and each subdirectory is in Tomcat Directory Layout.

First Start / Stop Checklist

StepCommand (Linux/macOS)
Start$CATALINA_HOME/bin/startup.sh
Verifycurl -I http://127.0.0.1:8080/
Stop$CATALINA_HOME/bin/shutdown.sh
Confirm stoppedcurl -I http://127.0.0.1:8080/ should fail to connect

If shutdown hangs, something may still hold port 8080—check logs under logs/ and see Common Install Problems below.

Common Install Problems

SymptomLikely causeFix
JAVA_HOME / JRE not foundJDK not installed or env var unsetInstall JDK 17+; set JAVA_HOME; reopen terminal
Address already in use (8080)Another Tomcat, Spring Boot, or app on 8080ss -tlnp | grep 8080 (Linux) or netstat -ano | findstr 8080 (Windows); stop conflict or change port in conf/server.xml
Blank page / connection refusedTomcat not started or wrong portCheck logs/catalina*.log; run catalina.sh run for console errors
Permission denied on LinuxRunning as wrong user after chown tomcatStart as tomcat user or fix ownership for your learning account
Garbled path on WindowsUnzipped under folder with Chinese/spacesMove to C:\apache-tomcat-10.1.x
Tomcat 10 + old WAR failsApp still uses javax.servletUse Tomcat 9 for legacy, or migrate app to Jakarta
Docker 8080 in useHost service already on 8080docker run -p 8081:8080 ... and open port 8081

Peek at logs when startup fails

bash
tail -50 logs/catalina.out          # if present
tail -50 logs/catalina.$(date +%Y-%m-%d).log

Windows: open the newest catalina.*.log under logs\ in a text editor.

Post-Install Checklist

  • java -version shows 17 or 21
  • Tomcat 10.1.x extracted or package installed
  • CATALINA_HOME points at install root (official zip method)
  • startup succeeds; browser or curl returns 200 on port 8080
  • You know where webapps/, conf/, and logs/ live
  • shutdown stops the server cleanly

What Comes Next

ChapterTopic
03 — Directory layoutEvery folder, env vars, package vs zip paths
04 — Start, stop, environmentcatalina.sh run, systemd, Windows service
07 — Deploying WARReplace the default apps with your WAR

FAQ

Do I need to install Tomcat if Spring Boot already runs on 8080?

For embedded Boot development, no. Install standalone Tomcat when you practice WAR deploy, shared servers, or ops tasks this track teaches.

Tomcat vs JDK—which install first?

Always JDK first. Tomcat is not a substitute for Java.

Can I run two Tomcat versions side by side?

Yes—use different install directories and different HTTP ports in each conf/server.xml. Only one process can bind to 8080.

Should I delete the default webapps (docs, examples)?

Not required for learning. Before production, remove sample apps and lock down Manager—see Tomcat Security Basics.

Official zip vs OS package—which should I use?

Use the official zip/tar.gz if you follow Hello Code paths literally. Use packages if your team standardizes on systemctl start tomcat10 and distro paths.

Why port 8080 and not 80?

Binding to port 80 on Linux requires root (or capabilities). Nginx on 80 proxying to Tomcat on 8080 is the usual production pattern.

WSL2 on Windows?

Install JDK and Tomcat inside WSL (Linux steps). Browse from Windows at http://127.0.0.1:8080/—same as other WSL services.