Instalando Tomcat 9 no Linux

Apache Tomcat 11 e OpenJDK 25 no Linux

Nota (2026): Artigo original de abril de 2017 (Tomcat 9.0.0.M21 + JRE 8 da Oracle). O título e a URL foram mantidos porque estão indexados; o procedimento abaixo instala o Apache Tomcat 11.0.25 com OpenJDK 25 LTS, as versões atuais em setembro de 2026.

O Tomcat continua sendo o container servlet mais usado em servidores Linux. Este howto instala a linha atual a partir do tarball oficial da Apache, com usuário dedicado e unidade systemd — no Ubuntu 24.04/22.04 e Debian equivalentes.

Qual versão usar

Em setembro de 2026 a Apache mantém três linhas estáveis. Para instalação nova, use a 11:

Tomcat Java mínimo API Situação
11.0.25 17+ Jakarta EE 11 (jakarta.*) atual — use este
10.1.59 11+ Jakarta EE 10 (jakarta.*) suportado
9.0.121 8+ Java EE 8 (javax.*) EOL em 31/03/2027

O Tomcat 11 implementa Servlet 6.1 / JSP 4.0 e exige Java 17 ou superior. O OpenJDK 25 é o LTS mais novo e roda nessa linha. Aplicações escritas para Tomcat 9 (javax.*) não sobem direto no 10/11 — precisam migrar o namespace com a ferramenta oficial. Se a app ainda for javax.* e você não pode migrar agora, veja a seção do Tomcat 9 no final.

Instalando o OpenJDK 25

Esqueça o tarball da Oracle com cookie de licença: no Ubuntu/Debian o OpenJDK entra pelo apt e recebe atualização de segurança junto com o sistema. No servidor, a variante headless basta (sem bibliotecas gráficas).

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

Se o pacote openjdk-25-jdk-headless não existir na sua release, instale o 21 (openjdk-21-jdk-headless) — o Tomcat 11 aceita qualquer Java ≥ 17. Confira o JAVA_HOME (o caminho muda entre amd64 e arm64):

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

Criando o grupo e o usuário tomcat

O processo não deve rodar como root. Conta de sistema, sem login e sem home extra:

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

Baixando e instalando o Tomcat 11

Pegue o tarball no CDN oficial e confira o SHA-512. A versão abaixo é a 11.0.25 (12/08/2026); se já houver uma 11.0.x mais nova em tomcat.apache.org/download-11.cgi, troque o 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

Memória da JVM fica no setenv.sh, que o catalina.sh carrega sozinho — assim você não mistura opção com espaço dentro do 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

Ajuste -Xmx à RAM da máquina. 1 GB é um ponto de partida razoável para um host pequeno.

Unidade systemd

Type=simple com catalina.sh run deixa o Java em primeiro plano, que é o modo que o systemd espera. (Os comandos essenciais do systemd cobrem start/stop/status com mais detalhe.)

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

Conferindo se subiu

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

A página padrão do Tomcat deve responder 200 em http://IP:8080/. Se a porta não abrir, o log em /usr/local/tomcat/logs/catalina.out e o journalctl mostram o motivo (JAVA_HOME errado é o mais comum).

Abra a 8080 no firewall só se o Tomcat for acessado de fora. Com proxy reverso na mesma máquina, deixe a 8080 só em localhost:

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

Manager (opcional)

O Manager e o Host Manager vêm desligados para o mundo: o RemoteAddrValve nas apps manager e host-manager só aceita localhost. Crie um usuário com senha forte — 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

Acesse http://127.0.0.1:8080/manager/html (SSH tunnel se o host for remoto). Não abra o Manager para a internet.

Porta 80: nginx na frente, não iptables

Em 2017 este artigo redirecionava 80→8080 com iptables NAT. Hoje o caminho certo é um proxy reverso: TLS, Host header e logs no nginx, Tomcat só em 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;
    }
}

Se você realmente quiser o NAT antigo (sem 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.

Ainda precisa do Tomcat 9?

Apps antigas em javax.* (Spring Boot 2, Java EE 8) não rodam no Tomcat 11. Duas saídas:

  • Migrar o WAR com o Tomcat Migration Tool for Jakarta EE e subir no 11.
  • Ficar no 9.0.x enquanto a app não migra. A linha 9.0 recebe correção até 31/03/2027; o procedimento é o mesmo deste artigo, trocando a URL de download para a 9.0.121 em download-90.cgi (Java 8+; OpenJDK 21 também serve).

Vídeo original (2017)

A gravação abaixo é da instalação original (Tomcat 9 milestone). O fluxo — usuário dedicado, tarball, serviço no boot — continua o mesmo; as versões e o Java, não.

Referências

Com isso você tem Tomcat 11 + OpenJDK 25 como serviço, conferido por checksum, sem JRE proprietário e com atualização pelo apt no lado Java. Na próxima correção da linha 11.0.x, basta trocar o tarball e repetir o chown — o JAVA_HOME e a unidade systemd continuam iguais.