Instalando Tomcat 9 en Linux

Mascote do LinuxPro instalando um módulo de aplicação em um rack de servidores Apache Tomcat

Nota (2026): Artículo original de abril de 2017 (Tomcat 9.0.0.M21 + JRE 8 de Oracle). El título y la URL se han mantenido porque están indexados; el procedimiento siguiente instala el Apache Tomcat 11.0.25 con OpenJDK 25 LTS, las versiones actuales en septiembre de 2026.

Tomcat sigue siendo el contenedor de servlets más usado en servidores Linux. Este howto instala la línea actual a partir del tarball oficial de Apache, con un usuario dedicado y una unidad systemd — en Ubuntu 24.04/22.04 y Debian equivalentes.

Qué versión usar

En septiembre de 2026 Apache mantiene tres líneas estables. Para una nueva instalación, use la 11:

Tomcat Java mínimo API Situación
11.0.25 17+ Jakarta EE 11 (jakarta.*) actual — use esta
10.1.59 11+ Jakarta EE 10 (jakarta.*) soportada
9.0.121 8+ Java EE 8 (javax.*) EOL en 31/03/2027

El Tomcat 11 implementa Servlet 6.1 / JSP 4.0 y requiere Java 17 o superior. OpenJDK 25 es el LTS más reciente y funciona en esa línea. Las aplicaciones escritas para Tomcat 9 (javax.*) no se despliegan directamente en 10/11 — necesitan migrar el namespace con la herramienta oficial. Si la app aún es javax.* y no puede migrar ahora, consulte la sección de Tomcat 9 al final.

Instalando OpenJDK 25

Olvide el tarball de Oracle con cookie de licencia: en Ubuntu/Debian OpenJDK se instala con apt y recibe actualizaciones de seguridad junto con el sistema. En el servidor, la variante headless es suficiente (sin bibliotecas gráficas).

sudo apt update
sudo apt install -y openjdk-25-jdk-headless
java -version

Si el paquete openjdk-25-jdk-headless no existe en tu release, instala 21 (openjdk-21-jdk-headless) — Tomcat 11 acepta cualquier Java ≥ 17. Consulta el JAVA_HOME (la ruta cambia entre amd64 y arm64):

JAVA_HOME=$(dirname "$(dirname "$(readlink -f "$(which java)")")")
echo "$JAVA_HOME"
# exemplo amd64: /usr/lib/jvm/java-25-openjdk-amd64

Creando el grupo y el usuario tomcat

El proceso no debe ejecutarse como root. Cuenta de sistema, sin inicio de sesión y sin home adicional:

sudo groupadd --system tomcat
sudo useradd --system --no-create-home --gid tomcat 
  --shell /usr/sbin/nologin --home-dir /usr/local/tomcat tomcat

Descargando e instalando Tomcat 11

Descarga el tarball en el CDN oficial y comprueba el SHA-512. La versión de abajo es la 11.0.25 (12/08/2026); si ya hay una 11.0.x más nueva en tomcat.apache.org/download-11.cgi, cambia el VER.

VER=11.0.25
cd /tmp
curl -fLO "https://dlcdn.apache.org/tomcat/tomcat-11/v${VER}/bin/apache-tomcat-${VER}.tar.gz"
curl -fLO "https://downloads.apache.org/tomcat/tomcat-11/v${VER}/bin/apache-tomcat-${VER}.tar.gz.sha512"
sha512sum -c "apache-tomcat-${VER}.tar.gz.sha512"

sudo mkdir -p /usr/local/tomcat
sudo tar -xzf "apache-tomcat-${VER}.tar.gz" -C /usr/local/tomcat --strip-components=1
sudo chown -R tomcat:tomcat /usr/local/tomcat
sudo find /usr/local/tomcat -type d -exec chmod 750 {} ;
sudo find /usr/local/tomcat -type f -exec chmod 640 {} ;
sudo chmod 750 /usr/local/tomcat/bin/*.sh

La memoria de la JVM queda en el setenv.sh, que el catalina.sh carga por sí solo — así no mezclas opciones con espacios dentro de systemd:

sudo tee /usr/local/tomcat/bin/setenv.sh > /dev/null << 'EOF'
export CATALINA_OPTS="-Xms512M -Xmx1024M -server"
export JAVA_OPTS="-Djava.awt.headless=true -Djava.security.egd=file:/dev/./urandom"
EOF
sudo chown tomcat:tomcat /usr/local/tomcat/bin/setenv.sh
sudo chmod 750 /usr/local/tomcat/bin/setenv.sh

Ajusta -Xmx a la RAM de la máquina. 1 GB es un punto de partida razonable para un host pequeño.

Unidad systemd

Type=simple con catalina.sh run deja Java en primer plano, que es el modo que espera systemd. (Los comandos esenciales de systemd cubren start/stop/status con más detalle).

JAVA_HOME=$(dirname "$(dirname "$(readlink -f "$(which java)")")")

sudo tee /etc/systemd/system/tomcat.service > /dev/null << EOF
[Unit]
Description=Apache Tomcat 11
After=network.target

[Service]
Type=simple
User=tomcat
Group=tomcat
Environment=JAVA_HOME=${JAVA_HOME}
Environment=CATALINA_HOME=/usr/local/tomcat
Environment=CATALINA_BASE=/usr/local/tomcat
WorkingDirectory=/usr/local/tomcat
ExecStart=/usr/local/tomcat/bin/catalina.sh run
SuccessExitStatus=143
Restart=on-failure
RestartSec=10
UMask=0007

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable --now tomcat
sudo systemctl status tomcat --no-pager

Comprobando que ha arrancado

ss -lntp | grep 8080
curl -I http://127.0.0.1:8080/
sudo journalctl -u tomcat -e --no-pager

La página por defecto de Tomcat debería responder 200 en http://IP:8080/. Si el puerto no se abre, el log en /usr/local/tomcat/logs/catalina.out y el journalctl muestran el motivo (JAVA_HOME incorrecto es lo más común).

Abra la 8080 en el firewall solo si se accede a Tomcat desde fuera. Con proxy inverso en la misma máquina, deje la 8080 solo en localhost:

# acesso direto (se precisar)
sudo ufw allow 8080/tcp comment 'Tomcat'

Manager (opcional)

El Manager y el Host Manager vienen desactivados para el mundo: el RemoteAddrValve en las apps manager e host-manager solo acepta localhost. Cree un usuario con contraseña fuerte — nunca admin/admin:

SENHA=$(openssl rand -base64 18)
echo "senha do manager: $SENHA"

sudo tee /usr/local/tomcat/conf/tomcat-users.xml > /dev/null << EOF
<?xml version="1.0" encoding="UTF-8"?>
<tomcat-users xmlns="https://tomcat.apache.org/xml"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="https://tomcat.apache.org/xml tomcat-users.xsd"
              version="1.0">
  <role rolename="manager-gui"/>
  <role rolename="admin-gui"/>
  <user username="admin" password="${SENHA}" roles="manager-gui,admin-gui"/>
</tomcat-users>
EOF
sudo chown tomcat:tomcat /usr/local/tomcat/conf/tomcat-users.xml
sudo chmod 640 /usr/local/tomcat/conf/tomcat-users.xml
sudo systemctl restart tomcat

Acceda http://127.0.0.1:8080/manager/html (Túnel SSH si el host es remoto). No exponga el Manager a Internet.

Puerto 80: nginx delante, no iptables

En 2017 este artículo redirigía 80→8080 con iptables NAT. Hoy el camino correcto es un proxy inverso: TLS, Host header y logs en nginx, Tomcat solo en 127.0.0.1:8080.

server {
    listen 80;
    server_name app.exemplo.com;

    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;
    }
}

Si realmente quieres el NAT antiguo (sin nginx):

sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
# persista a regra no firewall da distro (nftables/iptables-persistent/ufw),
# não no /etc/rc.local.

¿Todavía necesita Tomcat 9?

Aplicaciones antiguas en javax.* (Spring Boot 2, Java EE 8) no se ejecutan en Tomcat 11. Dos salidas:

  • Migrar el WAR con el Tomcat Migration Tool for Jakarta EE y desplegar en 11.
  • Quedarse en 9.0.x mientras la aplicación no migra. La línea 9.0 recibe correcciones hasta 31/03/2027; el procedimiento es el mismo que el de este artículo, cambiando la URL de descarga por la 9.0.121 en download-90.cgi (Java 8+; OpenJDK 21 también sirve).

Vídeo original (2017)

La grabación siguiente es de la instalación original (Tomcat 9 milestone). El flujo — usuario dedicado, tarball, servicio en el arranque — sigue siendo el mismo; las versiones y el Java, no.

Referencias

Con esto tienes Tomcat 11 + OpenJDK 25 como servicio, verificado mediante checksum, sin JRE propietario y con actualización mediante apt en el lado Java. En la próxima corrección de la línea 11.0.x, basta con cambiar el tarball y repetir el chown — el JAVA_HOME e la unidad systemd siguen igual.