Skip to main content
Advertisement

Tomcat Installation and Initial Setup

Apache Tomcat is the leading WAS (Web Application Server) for running Java Servlets and JSP. This chapter covers everything you need in production: JDK environment setup, version differences across Tomcat releases, and the directory structure after installation.


JDK Environment Setup

Tomcat requires a Java runtime. The minimum Java version required differs by Tomcat version.

Tomcat VersionMinimum JavaServlet SpecJSP SpecRecommendation
Tomcat 9Java 8+4.02.3Legacy systems
Tomcat 10Java 11+5.03.0Jakarta EE migration
Tomcat 10.1Java 11+6.03.1** Recommended (stable)**
Tomcat 11Java 17+6.14.0Latest features

Important: From Tomcat 10, the javax.* package namespace changed to jakarta.*. Code modifications are required when migrating from Tomcat 9 → 10.

Ubuntu — OpenJDK Installation

# Install OpenJDK 17 LTS (recommended for Tomcat 10.1+)
sudo apt update
sudo apt install -y openjdk-17-jdk

# Verify version
java -version
# openjdk version "17.0.x" ...

# Set JAVA_HOME (permanent)
echo 'export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64' | sudo tee -a /etc/environment
echo 'export PATH=$PATH:$JAVA_HOME/bin' | sudo tee -a /etc/environment
source /etc/environment

echo $JAVA_HOME
# /usr/lib/jvm/java-17-openjdk-amd64

CentOS/RHEL — OpenJDK Installation

# Install OpenJDK 17
sudo dnf install -y java-17-openjdk-devel

# Check JAVA_HOME
alternatives --list | grep java

# Create /etc/profile.d/java.sh
cat << 'EOF' | sudo tee /etc/profile.d/java.sh
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk
export PATH=$PATH:$JAVA_HOME/bin
EOF
source /etc/profile.d/java.sh

Installing Tomcat on Ubuntu/Debian

Method 1: APT Package Manager (Quick)

sudo apt update
sudo apt install -y tomcat10

# Check service status
sudo systemctl status tomcat10
sudo systemctl enable tomcat10
sudo systemctl start tomcat10

# Verify on default port 8080
curl -I http://localhost:8080
# HTTP/1.1 200
# Prepare installation directory
sudo mkdir -p /opt/tomcat

# Create dedicated user (security)
sudo useradd -r -m -U -d /opt/tomcat -s /bin/false tomcat

# Download Tomcat 10.1
TOMCAT_VERSION=10.1.20
cd /tmp
wget https://dlcdn.apache.org/tomcat/tomcat-10/v${TOMCAT_VERSION}/bin/apache-tomcat-${TOMCAT_VERSION}.tar.gz

# Extract
sudo tar -xzf apache-tomcat-${TOMCAT_VERSION}.tar.gz -C /opt/tomcat/
sudo ln -s /opt/tomcat/apache-tomcat-${TOMCAT_VERSION} /opt/tomcat/latest

# Set ownership
sudo chown -R tomcat: /opt/tomcat/latest
sudo chmod +x /opt/tomcat/latest/bin/*.sh

# Register Systemd service
sudo tee /etc/systemd/system/tomcat.service << 'EOF'
[Unit]
Description=Apache Tomcat Web Application Container
After=network.target

[Service]
Type=forking
User=tomcat
Group=tomcat

Environment="JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64"
Environment="CATALINA_HOME=/opt/tomcat/latest"
Environment="CATALINA_BASE=/opt/tomcat/latest"
Environment="CATALINA_PID=/opt/tomcat/latest/temp/tomcat.pid"
Environment="CATALINA_OPTS=-Xms512M -Xmx1024M -server -XX:+UseParallelGC"

ExecStart=/opt/tomcat/latest/bin/startup.sh
ExecStop=/opt/tomcat/latest/bin/shutdown.sh

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable tomcat
sudo systemctl start tomcat
sudo systemctl status tomcat

Running Tomcat with Docker

# Official Tomcat 10.1 + JDK 17 image
docker run -d \
--name tomcat \
-p 8080:8080 \
tomcat:10.1-jdk17

# Enable default management page (development only)
docker exec -it tomcat bash -c \
"cp -r /usr/local/tomcat/webapps.dist/* /usr/local/tomcat/webapps/"

# Verify at http://localhost:8080

Docker Compose Example

# docker-compose.yml
version: '3.8'
services:
tomcat:
image: tomcat:10.1-jdk17
container_name: tomcat-app
ports:
- "8080:8080"
volumes:
- ./webapps:/usr/local/tomcat/webapps
- ./conf/server.xml:/usr/local/tomcat/conf/server.xml:ro
- ./logs:/usr/local/tomcat/logs
environment:
- CATALINA_OPTS=-Xms512m -Xmx1024m
restart: unless-stopped

Tomcat Directory Structure

Understanding the directory structure helps you quickly locate configuration files.

$CATALINA_HOME/
├── bin/ ← Execution scripts
│ ├── startup.sh # Start Tomcat
│ ├── shutdown.sh # Stop Tomcat
│ ├── catalina.sh # Core script (called by startup.sh)
│ └── setenv.sh # JVM option injection (create if missing)

├── conf/ ← Configuration files
│ ├── server.xml # Core config (connectors, hosts, contexts)
│ ├── web.xml # Global servlet configuration
│ ├── context.xml # Global context configuration
│ ├── tomcat-users.xml # Admin account configuration
│ └── logging.properties # Log configuration

├── webapps/ ← Deployment directory
│ ├── ROOT/ # http://host:8080/ default app
│ ├── manager/ # Tomcat manager web app
│ ├── host-manager/ # Virtual host manager web app
│ └── myapp.war # WAR file → auto-extracted

├── logs/ ← Log files
│ ├── catalina.out # Standard output (main log)
│ ├── catalina.YYYY-MM-DD.log # Daily log
│ ├── localhost.YYYY-MM-DD.log # Virtual host log
│ └── access_log.YYYY-MM-DD.txt # Access log

├── lib/ ← Shared libraries (common to all apps)
│ └── servlet-api.jar, jsp-api.jar, ...

├── temp/ ← Temporary files (JVM temp dir)
└── work/ ← JSP compile cache
└── Catalina/
└── localhost/
└── ROOT/ # JSP → Java → .class

setenv.sh — JVM Option Configuration

The recommended way to inject JVM options before Tomcat starts.

# Create $CATALINA_HOME/bin/setenv.sh
cat << 'EOF' | sudo tee /opt/tomcat/latest/bin/setenv.sh
#!/bin/bash
# JVM heap memory
export CATALINA_OPTS="$CATALINA_OPTS -Xms512m -Xmx2g"

# GC settings (Java 17 defaults to G1GC)
export CATALINA_OPTS="$CATALINA_OPTS -XX:+UseG1GC"
export CATALINA_OPTS="$CATALINA_OPTS -XX:MaxGCPauseMillis=200"

# GC log (for performance analysis)
export CATALINA_OPTS="$CATALINA_OPTS -Xlog:gc*:file=/opt/tomcat/latest/logs/gc.log:time,uptime:filecount=5,filesize=20m"

# Server mode
export CATALINA_OPTS="$CATALINA_OPTS -server"

# Timezone
export CATALINA_OPTS="$CATALINA_OPTS -Duser.timezone=Asia/Seoul"

# Encoding
export JAVA_OPTS="$JAVA_OPTS -Dfile.encoding=UTF-8"
EOF

sudo chmod +x /opt/tomcat/latest/bin/setenv.sh
sudo chown tomcat: /opt/tomcat/latest/bin/setenv.sh

Service Management Commands

# Start / Stop / Restart / Status
sudo systemctl start tomcat
sudo systemctl stop tomcat
sudo systemctl restart tomcat
sudo systemctl status tomcat

# Real-time log monitoring
sudo tail -f /opt/tomcat/latest/logs/catalina.out

# Validate configuration
sudo -u tomcat /opt/tomcat/latest/bin/catalina.sh configtest

# Check port usage
sudo ss -tlnp | grep 8080

Firewall Configuration

# Ubuntu/Debian (ufw)
sudo ufw allow 8080/tcp
sudo ufw reload

# CentOS/RHEL (firewalld)
sudo firewall-cmd --permanent --add-port=8080/tcp
sudo firewall-cmd --reload

Verifying Installation

# Check Tomcat version
/opt/tomcat/latest/bin/version.sh

# Example output
# Server version: Apache Tomcat/10.1.20
# JVM Version: 17.0.x

# Check HTTP response
curl -s -o /dev/null -w "%{http_code}" http://localhost:8080
# 200

Summary

ItemDetails
Tomcat version10.1.x recommended (Java 11+), 11.x (Java 17+)
Java requirementTomcat 9: Java 8+, Tomcat 10+: Java 11+
JVM option location$CATALINA_HOME/bin/setenv.sh (recommended)
Key config filesconf/server.xml, conf/web.xml, conf/context.xml
Deployment directorywebapps/ (WAR auto-extraction)
Service managementsystemctl start/stop/restart tomcat
Advertisement