Option 1: reverse proxy (recommended)
Nginx listens on 80 and 443 and forwards to Tomcat on 8080. You also get TLS certificates from Let's Encrypt, compression and static file caching. See Nginx reverse proxy for a Java app and Tomcat behind Nginx. Almost every production setup uses this.
Option 2: let the service bind low ports
Linux has a capability for exactly this. Edit the service with a drop-in (service name tomcat10 on Debian and Ubuntu, tomcat elsewhere):
sudo systemctl edit tomcat10
# add:
[Service]
AmbientCapabilities=CAP_NET_BIND_SERVICE
Then change the connector in server.xml from port="8080" to port="80", and restart. Tomcat now binds port 80 as the unprivileged tomcat user. For HTTPS you must configure a keystore in the connector, which means converting Let's Encrypt certificates and reloading Tomcat after each renewal. That extra work is a good reason to use Option 1.
If the service fails to start, look at journalctl -u tomcat10 -n 50. "Permission denied" means the capability was not applied. Check with systemctl cat tomcat10 that your drop-in is listed.
Option 3: redirect with the firewall
Leave Tomcat on 8080 and redirect incoming port 80 to it:
sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
This is easy for a test but easy to forget, and it does not give you HTTPS. The rule disappears after a reboot unless you save it.
What not to do
- Do not run Tomcat as root. A bug in any web application would then give an attacker full control of the server.
- Do not use
setcapon the Java binary. It breaks library loading in a way that is hard to debug. - Do not open port 8080 to the internet if you serve through a proxy. Bind the connector to
address="127.0.0.1".
Questions about tomcat on port 80 and 443
Can I use authbind?
On Debian the package supports it (AUTHBIND=yes in /etc/default/tomcat10). A reverse proxy is still simpler and gives you TLS.
Last updated October 29, 2026.