Installing Apache Tomcat on CentOS Stream 9: A Real-World Production Guide

CentOS tutorial - IT technology blog
CentOS tutorial - IT technology blog

Why Tomcat on VMs is Still the Top Choice for Enterprises

After six months of directly migrating systems from CentOS 7 to CentOS Stream 9, I’ve realized one thing: even though Docker and Kubernetes are all the rage, running Apache Tomcat directly on virtual machines (VMs) still has its place. For legacy Java Web applications, this approach optimizes I/O performance and makes debugging significantly easier. CentOS Stream 9 paired with JDK 17 or 21 is currently a highly stable combination for production.

In a project I recently deployed, the biggest challenge wasn’t the code. Issues usually stemmed from service management and permission conflicts in RHEL-based environments. If you don’t master Firewall or SELinux configuration, you could spend all day just figuring out why the app can’t connect externally.

System Requirements

You need a clean CentOS Stream 9 (or Rocky/AlmaLinux) server. In this guide, I’m choosing Tomcat 10 to leverage the power of Jakarta EE. A quick tip: prepare a server with at least 2GB of RAM for smooth Java performance.

Step 1: Install OpenJDK 17 LTS

Tomcat cannot run without Java. I prefer OpenJDK 17 because it is an LTS version with excellent performance and long-term support.

sudo dnf update -y
sudo dnf install java-17-openjdk-devel -y

Once installed, run this command to verify:

java -version

If you see the line openjdk version "17.x.x", the foundation is ready.

Step 2: Create a Dedicated User – Never Use Root

Many developers have the habit of running Tomcat with root privileges for “convenience.” This is a dangerous mistake. If the app has a Remote Code Execution vulnerability, a hacker could take full control of your server. Create a dedicated user without shell access to isolate the service.

sudo useradd -m -U -d /opt/tomcat -s /bin/false tomcat

This command creates a tomcat user with a home directory at /opt/tomcat but disables direct login capabilities.

Step 3: Download and Extract Apache Tomcat 10

Go to the official website to get the latest 10.1.x link. Avoid blindly copying old versions as security patches are updated continuously.

cd /tmp
wget https://dlcdn.apache.org/tomcat/tomcat-10/v10.1.18/bin/apache-tomcat-10.1.18.tar.gz

# Extract directly to the destination directory
sudo tar -xf apache-tomcat-10.1.18.tar.gz -C /opt/tomcat --strip-components=1

Next, transfer directory ownership to the correct owner:

sudo chown -R tomcat:tomcat /opt/tomcat
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/

Step 4: Professional Tomcat Management with Systemd

Don’t use the startup.sh file manually. Turn Tomcat into a service so it starts automatically with the OS. This also allows for centralized log management via journalctl.

Create the service configuration file:

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

Paste the following content. Note the -Xmx1024M parameter—if your server has 4GB of RAM, increase this to 2048M for optimization.

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

[Service]
Type=forking

User=tomcat
Group=tomcat

Environment="JAVA_HOME=/usr/lib/jvm/jre"
Environment="JAVA_OPTS=-Djava.awt.headless=true -Djava.security.egd=file:/dev/./urandom"

Environment="CATALINA_BASE=/opt/tomcat"
Environment="CATALINA_HOME=/opt/tomcat"
Environment="CATALINA_PID=/opt/tomcat/temp/tomcat.pid"
Environment="CATALINA_OPTS=-Xms512M -Xmx1024M -server -XX:+UseG1GC"

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

[Install]
WantedBy=multi-user.target

Activate the service immediately:

sudo systemctl daemon-reload
sudo systemctl enable --now tomcat

Step 5: Open Firewall Ports

By default, Tomcat listens on port 8080, but CentOS 9 blocks all external connections. You need to open the “door” for it:

sudo firewall-cmd --permanent --add-port=8080/tcp
sudo firewall-cmd --reload

If you change the port in server.xml, don’t forget to update the firewall command accordingly.

Step 6: Set Up Web Manager

To use the web management interface, you need to grant permissions in the tomcat-users.xml file.

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

Add an admin user with a strong password:

<role rolename="manager-gui"/>
<user username="admin" password="SuperStrongPassword2024!" roles="manager-gui"/>

By default, Tomcat only allows access from localhost. If you want to access it remotely from your personal IP, you must edit webapps/manager/META-INF/context.xml and comment out the Valve section that blocks IP addresses.

Conclusion: Lessons from Real-World Operations

Installation is just the beginning. To keep the system running stably 24/7, keep these 3 key points in mind:

  • Monitor logs regularly: The catalina.out file is the first place you should check when the app encounters issues.
  • Optimize RAM: Never let -Xmx exceed 70% of the total server RAM; otherwise, the OS will kill the Tomcat process if memory overflows.
  • Use a Reverse Proxy: In practice, I always place Nginx in front of Tomcat. Nginx handles SSL and gzip compression, allowing Tomcat to focus solely on processing Java logic.

I hope these insights help you deploy your systems faster and more securely. Good luck!

Share: