BLOG POSTS
How to Install Apache Tomcat 10 on Ubuntu 24

How to Install Apache Tomcat 10 on Ubuntu 24

Apache Tomcat 10 represents a significant milestone in the Java servlet container landscape, introducing Jakarta EE 9 support with the namespace migration from javax.* to jakarta.*. If you’re running Ubuntu 24 (Jammy), setting up Tomcat 10 properly requires understanding both the traditional installation methods and modern containerized approaches. This guide walks through multiple installation techniques, covers essential configuration tweaks, and addresses the gotchas that’ll save you hours of debugging servlet deployment issues.

Understanding Tomcat 10 Architecture Changes

Tomcat 10 isn’t just a version bump – it’s a breaking change that implements Jakarta EE 9 specifications. The major shift involves package namespace changes where all javax.servlet.* packages become jakarta.servlet.*. This affects every servlet, JSP, and related Java EE component.

Key architectural improvements include:

  • Enhanced memory management with improved garbage collection integration
  • Better HTTP/2 support with reduced overhead
  • Streamlined connector architecture for improved performance
  • Updated security defaults with stronger cipher suites
Feature Tomcat 9 Tomcat 10 Impact
Servlet API javax.servlet.* jakarta.servlet.* Breaking change – requires code migration
Java Version Java 8+ Java 11+ Modern JVM features, better performance
Memory Usage Baseline ~15% reduction Lower resource footprint
HTTP/2 Performance Standard ~25% improvement Better concurrent request handling

Method 1: Manual Installation from Apache Archive

The manual installation gives you complete control over the Tomcat setup and is preferred for production environments where you need specific versions or custom configurations.

First, ensure your system is updated and has Java installed:

sudo apt update && sudo apt upgrade -y
sudo apt install openjdk-17-jdk wget curl -y
java -version

Create a dedicated tomcat user for security isolation:

sudo groupadd tomcat
sudo useradd -s /bin/false -g tomcat -d /opt/tomcat tomcat

Download and extract Tomcat 10:

cd /tmp
wget https://downloads.apache.org/tomcat/tomcat-10/v10.1.16/bin/apache-tomcat-10.1.16.tar.gz
sudo tar xzvf apache-tomcat-10.1.16.tar.gz -C /opt/tomcat --strip-components=1

Set proper ownership and permissions:

sudo chown -R tomcat: /opt/tomcat
sudo sh -c 'chmod +x /opt/tomcat/bin/*.sh'
sudo chmod -R g+r /opt/tomcat/conf
sudo chmod g+x /opt/tomcat/conf
sudo chown -R tomcat /opt/tomcat/webapps/ /opt/tomcat/work/ /opt/tomcat/temp/ /opt/tomcat/logs/

Create a systemd service file for automatic startup:

sudo nano /etc/systemd/system/tomcat.service

Add this configuration:

[Unit]
Description=Apache Tomcat Web Application Container
After=network.target

[Service]
Type=forking

Environment=JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
Environment=CATALINA_PID=/opt/tomcat/temp/tomcat.pid
Environment=CATALINA_HOME=/opt/tomcat
Environment=CATALINA_BASE=/opt/tomcat
Environment='CATALINA_OPTS=-Xms512M -Xmx1024M -server -XX:+UseParallelGC'
Environment='JAVA_OPTS=-Djava.awt.headless=true -Djava.security.egd=file:/dev/./urandom'

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

User=tomcat
Group=tomcat
UMask=0007
RestartSec=10
Restart=always

[Install]
WantedBy=multi-user.target

Enable and start the service:

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

Method 2: APT Package Installation

Ubuntu 24’s repositories include Tomcat 10 packages, making installation straightforward but with less flexibility:

sudo apt update
sudo apt install tomcat10 tomcat10-webapps tomcat10-admin -y

The APT installation automatically:

  • Creates tomcat user and group
  • Sets up systemd service
  • Configures proper file permissions
  • Installs default webapps and admin tools

Key file locations for APT installation:

  • Installation directory: /usr/share/tomcat10
  • Configuration: /etc/tomcat10
  • Webapps: /var/lib/tomcat10/webapps
  • Logs: /var/log/tomcat10

Essential Configuration and Security Hardening

Default Tomcat installations are notoriously insecure. Here’s how to lock things down properly.

Configure admin users by editing tomcat-users.xml:

sudo nano /opt/tomcat/conf/tomcat-users.xml

Add these roles and users before the closing tag:

<role rolename="manager-gui" />
<role rolename="manager-script" />
<role rolename="manager-jmx" />
<role rolename="manager-status" />
<role rolename="admin-gui" />
<role rolename="admin-script" />
<user username="admin" password="StrongPassword123!" roles="manager-gui,admin-gui" />
<user username="deployer" password="DeployerPass456!" roles="manager-script" />

Secure the Manager app by restricting access. Edit the context file:

sudo nano /opt/tomcat/webapps/manager/META-INF/context.xml

Replace the Valve configuration to allow specific IP ranges:

<Valve className="org.apache.catalina.valves.RemoteAddrValve"
       allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1|192\.168\.\d+\.\d+" />

Configure JVM memory settings for optimal performance. Edit the service file:

Environment='CATALINA_OPTS=-Xms1024M -Xmx2048M -server -XX:+UseG1GC -XX:MaxGCPauseMillis=200'

Firewall Configuration and Reverse Proxy Setup

Configure UFW to allow Tomcat traffic:

sudo ufw allow 8080/tcp
sudo ufw allow 8443/tcp
sudo ufw enable

For production deployments, set up nginx as a reverse proxy. Install nginx:

sudo apt install nginx -y

Create a virtual host configuration:

sudo nano /etc/nginx/sites-available/tomcat

Add this configuration:

server {
    listen 80;
    server_name your-domain.com;

    location / {
        proxy_pass http://localhost:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_connect_timeout 300s;
        proxy_send_timeout 300s;
        proxy_read_timeout 300s;
    }
}

Enable the site:

sudo ln -s /etc/nginx/sites-available/tomcat /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx

Real-World Deployment Examples

Here’s a practical example of deploying a Jakarta EE 9 application. Create a simple servlet:

package com.example.webapp;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        out.println("<h1>Hello from Tomcat 10 on Ubuntu 24!</h1>");
        out.println("<p>Jakarta EE 9 is working properly.</p>");
    }
}

Deploy applications using the manager interface or by copying WAR files:

sudo cp myapp.war /opt/tomcat/webapps/
sudo chown tomcat:tomcat /opt/tomcat/webapps/myapp.war

Performance Tuning and Monitoring

Enable JMX monitoring by adding these JVM options:

Environment='CATALINA_OPTS=-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9999 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false'

Monitor Tomcat performance with these key metrics:

Metric Good Range Warning Signs Monitoring Command
Memory Usage <80% of heap >90% consistently jstat -gc [pid]
Thread Count <200 active >500 active Check manager app
Response Time <200ms average >1000ms average Access log analysis
Error Rate <1% >5% Error log monitoring

Common Issues and Troubleshooting

The most frequent problem is the “javax vs jakarta” namespace issue. If you’re migrating applications from Tomcat 9, use the migration tool:

cd /opt/tomcat/bin
java -jar jakartaee-migration-1.0.0.jar ../webapps/oldapp.war ../webapps/newapp.war

Port binding issues often occur when other services occupy port 8080:

sudo netstat -tlnp | grep :8080
sudo lsof -i :8080

Memory errors typically manifest as OutOfMemoryError. Check current usage:

sudo -u tomcat jcmd $(pgrep -f tomcat) VM.info
sudo -u tomcat jcmd $(pgrep -f tomcat) GC.run_finalization

Permission problems are common after manual installations:

sudo chown -R tomcat:tomcat /opt/tomcat
sudo find /opt/tomcat -type d -exec chmod 755 {} \;
sudo find /opt/tomcat -type f -exec chmod 644 {} \;
sudo chmod +x /opt/tomcat/bin/*.sh

Integration with Development Tools

For IDE integration, configure remote debugging by adding these JVM options:

Environment='CATALINA_OPTS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:8000'

Maven deployment configuration for automated builds:

<plugin>
    <groupId>org.apache.tomcat.maven</groupId>
    <artifactId>tomcat7-maven-plugin</artifactId>
    <version>2.2</version>
    <configuration>
        <url>http://localhost:8080/manager/text</url>
        <server>tomcat-server</server>
        <path>/myapp</path>
    </configuration>
</plugin>

Docker containerization for development consistency:

FROM tomcat:10.1-jdk17-openjdk-slim
COPY target/myapp.war /usr/local/tomcat/webapps/
EXPOSE 8080
CMD ["catalina.sh", "run"]

This setup provides a robust foundation for running Jakarta EE applications on Ubuntu 24. The namespace migration requires careful attention, but the performance improvements and modern Java features make Tomcat 10 worth the upgrade effort. Regular monitoring and proper security configuration ensure your deployment remains stable and secure in production environments.

For additional information, check the official Apache Tomcat 10 documentation and the Jakarta EE specifications for detailed API references.



This article incorporates information and material from various online sources. We acknowledge and appreciate the work of all original authors, publishers, and websites. While every effort has been made to appropriately credit the source material, any unintentional oversight or omission does not constitute a copyright infringement. All trademarks, logos, and images mentioned are the property of their respective owners. If you believe that any content used in this article infringes upon your copyright, please contact us immediately for review and prompt action.

This article is intended for informational and educational purposes only and does not infringe on the rights of the copyright owners. If any copyrighted material has been used without proper credit or in violation of copyright laws, it is unintentional and we will rectify it promptly upon notification. Please note that the republishing, redistribution, or reproduction of part or all of the contents in any form is prohibited without express written permission from the author and website owner. For permissions or further inquiries, please contact us.

Leave a reply

Your email address will not be published. Required fields are marked