Skip to content

Apache Tomcat Hosting: How to Install Tomcat 11 on Ubuntu and Run It Behind Nginx

5 min read

Applies to: Apache Tomcat 11.0 and 10.1 from the Ubuntu 26.04 and 24.04 and Debian 13 repositories; tested with Tomcat 11.0.22 and OpenJDK 25.0.4 on Ubuntu 26.04.1, with Nginx 1.28.3 as reverse proxy

Apache Tomcat runs Java web applications: servlets, JSP pages and .war files. It is a Java program that runs all the time and listens on its own port (8080 by default), so “Tomcat hosting” in practice means a server where you can install Java and keep a service running, such as a VPS or a dedicated server with root access. This guide installs Tomcat from the Ubuntu repositories, deploys an application and puts it safely behind Nginx.

Which Tomcat version?

According to the Apache Tomcat project:

  • Tomcat 11.0: Servlet 6.1 (Jakarta EE 11), Java 17 or later.
  • Tomcat 10.1: Servlet 6.0 (Jakarta EE 10), Java 11 or later.
  • Tomcat 9.0: Servlet 4.0 (Java EE 8), the last version that uses the old javax.* package names.

An application built for Tomcat 9 (javax.servlet) doesn’t run on Tomcat 10.1 or 11 without changes; the Tomcat project offers a migration tool for that. Check what your application needs first.

What the repositories offer at the time of writing:

  • Ubuntu 26.04: tomcat11 (11.0.22) and tomcat10 (10.1.55); the default Java is OpenJDK 25.
  • Ubuntu 24.04: tomcat10 (10.1.55) only.
  • Debian 13: tomcat11 (11.0.22) and tomcat10 (10.1.55).
  • tomcat9 has no install candidate on any of them, so old guides that use it fail.

1. Install Tomcat

sudo apt update
sudo apt install tomcat11 tomcat11-admin

On Ubuntu 24.04 use tomcat10 tomcat10-admin and replace 11 with 10 in the paths below. apt pulls in a Java runtime if none is installed; tomcat11-admin adds the web-based Manager. The package enables and starts tomcat11.service. Check it:

systemctl status tomcat11
curl -I http://localhost:8080

A working install answers HTTP/1.1 200, and the default page says “It works !”.

2. Know where things are

  • /etc/tomcat11/: configuration (server.xml for ports, tomcat-users.xml for Manager logins).
  • /var/lib/tomcat11/webapps/: your applications. ROOT is the site at /.
  • /var/log/tomcat11/: logs; journalctl -u tomcat11 shows the service output.
  • /etc/default/tomcat11: Java options. For example, to give Tomcat up to 1 GB of memory: JAVA_OPTS="-Djava.awt.headless=true -Xmx1g", then sudo systemctl restart tomcat11.

3. Deploy a WAR file

Copy the file into webapps; Tomcat unpacks and starts it by itself:

sudo cp hello.war /var/lib/tomcat11/webapps/
sudo chown tomcat:tomcat /var/lib/tomcat11/webapps/hello.war

The log confirms it:

INFO [Catalina-utility-1] org.apache.catalina.startup.HostConfig.deployWAR Deployment of web application archive [/var/lib/tomcat11/webapps/hello.war] has finished in [200] ms

The application is then at http://localhost:8080/hello/. The file name decides the path; name it ROOT.war to serve it at / (remove the default ROOT folder first).

4. Secure the Manager

The Manager at /manager/html can deploy and remove applications, so treat it like a root login. Add a user to /etc/tomcat11/tomcat-users.xml, inside <tomcat-users>:

<user username="admin" password="use-a-long-password" roles="manager-gui"/>

Restart Tomcat. Without a login the Manager answers 401. The manager-gui role opens the web page only; the text interface used by scripts (/manager/text) needs manager-script and returned 403 for this user.

Important: in our test, Ubuntu’s /etc/tomcat11/Catalina/localhost/manager.xml has no address restriction, so the Manager accepted a login from a non-local address. Limit it to the server itself by adding a valve inside the Context element of that file:

<Context path="/manager"
    docBase="/usr/share/tomcat11-admin/manager"
    antiResourceLocking="false" privileged="true">
  <Valve className="org.apache.catalina.valves.RemoteCIDRValve" allow="127.0.0.0/8, ::1/128"/>
</Context>

After a restart, the same login from another address got 403 and from 127.0.0.1 still worked. To reach it from your computer, use an SSH tunnel: ssh -L 8080:127.0.0.1:8080 user@your-server, then open http://localhost:8080/manager/html.

5. Put Tomcat behind Nginx

Visitors should reach your application on ports 80 and 443, not 8080. Make Tomcat listen on localhost only, in /etc/tomcat11/server.xml:

<Connector port="8080" address="127.0.0.1" protocol="HTTP/1.1"

Then install Nginx and proxy to it. This server block also blocks the Manager from outside, because requests through the proxy arrive from 127.0.0.1 and would pass the valve:

server {
    listen 80;
    server_name example.com;

    location /manager/ {
        return 403;
    }
    location / {
        proxy_pass http://127.0.0.1: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;
    }
}

In our test, port 8080 was no longer reachable from outside, the application loaded through Nginx and /manager/html returned 403. Add HTTPS with a certificate on Nginx and allow only ports 80, 443 and SSH in the firewall (UFW on Ubuntu). If you prefer Apache in front, see Apache as a reverse proxy.

Where to run it

Tomcat needs root access to install, and Java needs memory of its own: an idle Tomcat 11 with no application of ours used about 300 MB in our test. Size the server for your application on top of that. A KVM VPS gives you full root access for this. If you’d rather have someone set it up, our engineers can help.

Official documentation: tomcat11 package for Ubuntu 26.04.

Was this answer helpful?

Still stuck? Open a ticket