 |
|
| |
| Introduction
| |
Servlets and JavaServer Pages (JSP) are the long-standing way to build dynamic web
applications in Java: a servlet is a Java class that handles requests on the server, and a JSP is an HTML
page with embedded Java that is compiled into a servlet behind the scenes. Today these specifications live
under Jakarta EE (renamed from Java EE), as Jakarta Servlet and Jakarta Server
Pages, and the standard engine that runs them is Apache
Tomcat.
The modern pattern is simple: run Tomcat as a Java service on the VPS, and put
Apache in front of it as a reverse
proxy to handle the public HTTP and HTTPS traffic. This replaces the old mod_jserv / mod_jk
connectors that earlier handbooks described. It works on both FreeBSD 15 and Rocky Linux 10.
| |
| Installing Java and Tomcat
| |
Tomcat needs a Java runtime. Tomcat 11 (the current release, implementing Jakarta Servlet 6.1
and JSP 4.0) requires Java 17 or newer; the Java 21 LTS is a good choice.
On FreeBSD 15, both are packaged:
# pkg install openjdk21 tomcat11
# sysrc tomcat11_enable=YES
# service tomcat11 start
# # Tomcat is installed under /usr/local/apache-tomcat-11.0
On Rocky Linux 10, install Java from the repositories and Tomcat by hand (it is not in
the base repositories), then run it under a dedicated, unprivileged account:
# dnf install java-21-openjdk java-21-openjdk-devel
# useradd -r -m -U -d /opt/tomcat -s /sbin/nologin tomcat
# curl -L https://dlcdn.apache.org/tomcat/tomcat-11/v11.0.x/bin/apache-tomcat-11.0.x.tar.gz \
| tar xz -C /opt/tomcat --strip-components=1
# chown -R tomcat:tomcat /opt/tomcat
Then create a systemd service at /etc/systemd/system/tomcat.service:
[Unit]
Description=Apache Tomcat
After=network.target
[Service]
Type=forking
User=tomcat
Group=tomcat
Environment=JAVA_HOME=/usr/lib/jvm/jre-21-openjdk
Environment=CATALINA_HOME=/opt/tomcat
ExecStart=/opt/tomcat/bin/startup.sh
ExecStop=/opt/tomcat/bin/shutdown.sh
[Install]
WantedBy=multi-user.target
# systemctl daemon-reload
# systemctl enable --now tomcat
| |
| Deploying an Application
| |
Tomcat listens on port 8080 and serves applications from its webapps/ directory. A Java
web application is packaged as a single .war file (a Web Application Archive). Drop it into
webapps/ and Tomcat auto-deploys it — app.war becomes available under the
/app path, while the special ROOT application answers the bare /:
# FreeBSD: cp app.war /usr/local/apache-tomcat-11.0/webapps/
# Rocky Linux: cp app.war /opt/tomcat/webapps/ && chown tomcat:tomcat /opt/tomcat/webapps/app.war
Visit http://your-domain.example:8080/app to confirm it is running. Tomcat compiles each JSP
into a servlet on its first request, so the first hit to a new page is a little slower than later ones.
Watch logs/catalina.out (under the Tomcat directory) for startup and deployment messages.
| |
| Putting Apache in Front
| |
Rather than exposing port 8080 to the world, let Apache handle public traffic and forward it to
Tomcat — this is where you add HTTPS, virtual hosts, and access control. Enable the proxy modules
(see Apache’s Dynamic Modules
section — mod_proxy and mod_proxy_http), then add a virtual host:
<VirtualHost *:80>
ServerName app.example.com
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:8080/
ProxyPassReverse / http://127.0.0.1:8080/
</VirtualHost>
This is the modern replacement for the old mod_jk connector. Add
HTTPS to this virtual host so visitors
are encrypted end to end, and put the same name-based hosting to work for
multiple domains. If you prefer
Tomcat’s binary AJP protocol, enable mod_proxy_ajp instead and proxy to
ajp://127.0.0.1:8009/ — but AJP is disabled by default in modern Tomcat and must be enabled
and given a secret in conf/server.xml first, so plain HTTP proxying is usually simpler.
| |
| Securing the Setup
| |
|
TIP: Bind Tomcat to localhost so only Apache can reach it — set
address="127.0.0.1" on the HTTP connector in conf/server.xml — and once the
reverse proxy works, do not open port 8080 in the firewall. Leave Tomcat’s
Manager and Host Manager web apps disabled, or restrict them by IP and set a
strong password in conf/tomcat-users.xml — they can deploy and undeploy code.
Finally, patch the JDK and Tomcat as part of your
routine updates.
|
| |
| The Modern Landscape
| |
Two things are worth knowing if you are coming from older Java documentation. First, when Java EE
became Jakarta EE, the package namespace changed from javax.* to jakarta.* (as of
Jakarta EE 9). Tomcat 11 and 10.1 use jakarta.*; Tomcat 9 is the last
release on the old javax.* API, so use it only to run a legacy application you cannot recompile.
Second, many new Java web applications are built with frameworks such as Spring Boot, which
embed Tomcat (or Jetty) and ship as a single self-contained executable JAR. You run one with
java -jar app.jar, manage it as a service exactly like Tomcat above, and reverse-proxy it from
Apache the same way — with no separate Tomcat install to maintain.
| |
| Documentation
| |
|
Toll Free 1-866-GSP-4400 • 1-301-464-9363 • service@gsp.com
Copyright © 1994-2026 GSP Services, Inc.
|