
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
- Download do Tomcat 11
- Which version? (tabela oficial)
- Documentação do Tomcat 11
- Fim do suporte do Tomcat 9.0.x
- Migração javax → jakarta
- OpenJDK nos repositórios Ubuntu
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.