Introducción
Cuando construí nuestra aplicación financiera en Tomcat, rápidamente aprendí que poner Tomcat directamente en Internet público no era una buena idea. Funcionó al principio, pero era frágil, difícil de asegurar y casi imposible de mantener de manera fluida durante los despliegues.
Eventualmente, decidí colocar Nginx frente a Tomcat y dejar que Nginx manejara todo lo que Tomcat no hace bien, especialmente la terminación SSL, el modo de mantenimiento, la caché de archivos estáticos y ocultar los detalles de la infraestructura interna.
Este artículo explica la configuración exacta que utilizo en producción hoy. No es una guía genérica. Está escrita específicamente para el sistema financiero que desplegué, e incluye configuraciones reales y la razón detrás de cada decisión.
Por qué necesitaba Nginx frente a Tomcat
1. Una página de mantenimiento limpia cuando Tomcat se reinicia
En un sistema financiero, a menudo tenemos que reiniciar Tomcat durante despliegues o mantenimiento. Si Tomcat está caído, el usuario nunca debería ver una página 503 de Tomcat que exponga información del servidor.
Con Nginx, los usuarios siempre ven una página de mantenimiento amigable, incluso si Tomcat está completamente fuera de línea. Nginx captura la respuesta 502 o 503 y sirve una página HTML estática que preparé.
2. SSL es mucho más fácil en Nginx
Configurar SSL dentro de Tomcat es innecesariamente complicado. Tienes que convertir certificados en un almacén de claves de Java, gestionar el conector y lidiar con múltiples formatos.
Con Nginx, SSL es simple. Solo necesito dos archivos, un certificado y una clave privada. Nginx termina HTTPS, y Tomcat solo recibe HTTP sin formato desde localhost. La renovación del certificado y la depuración también son más fáciles.
3. Tomcat está completamente oculto del mundo exterior
Por razones de seguridad, no quiero que Tomcat exponga sus puertos o información del servidor a los usuarios públicos. Tomcat solo escucha en 127.0.0.1:8080.
Si alguien intenta escanear mi servidor, no puede detectar que Tomcat existe en absoluto.
4. Encabezados grandes para aprobaciones financieras
Algunas operaciones de aprobación en el sistema envían una larga lista de IDs de aplicaciones financieras en el encabezado o la cadena de consulta.
Para soportar estos encabezados grandes, configuré Nginx para permitir búferes de encabezado más grandes. Sin esto, algunas solicitudes fallarían porque el tamaño de encabezado predeterminado es demasiado pequeño.
5. Subidas de archivos grandes
Los usuarios suben contratos, facturas y documentos escaneados. Establecí un límite de tamaño de subida limpio en Nginx para que los archivos grandes ni siquiera lleguen a Tomcat a menos que pasen primero la validación de Nginx.
6. Contenido estático más rápido (CSS, JS, íconos)
Aunque Tomcat puede servir archivos estáticos, Nginx es mucho más rápido. Habilité la caché para activos estáticos, así que Nginx los sirve directamente sin molestar a Tomcat.
7. Timeouts personalizados para operaciones de larga duración
Al algunos procesos en un sistema financiero les lleva más tiempo, como la generación de informes o la aprobación por lotes.
Nginx me da control total sobre los timeouts del proxy para que los usuarios no reciban errores 504 inesperados.
La configuración HTTPS de Nginx que utilizo
Mantengo este archivo en:
/etc/nginx/sites-available/myapp_https
Aquí está la configuración real, simplificada para el artículo pero aún precisa.
server {
listen 443 ssl;
server_name finance.example.com;
ssl_certificate /opt/myapp/keystore/app.crt;
ssl_certificate_key /opt/myapp/keystore/app.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_protocols TLSv1.2;
ssl_prefer_server_ciphers on;
large_client_header_buffers 4 65k;
client_max_body_size 100m;
error_page 502 503 = @maintenance;
error_page 404 = @errors;
access_log /opt/myapp/nginx/logs/access.log;
error_log /opt/myapp/nginx/logs/error.log;
location / {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_pass http://127.0.0.1:8080;
proxy_buffering off;
proxy_buffer_size 128k;
proxy_buffers 100 128k;
proxy_connect_timeout 180;
proxy_send_timeout 180;
proxy_read_timeout 180;
send_timeout 180;
location ~* \.(css|js|jpg|gif|ico)$ {
proxy_cache cache;
proxy_cache_key $host$uri$is_args$args;
proxy_cache_valid 200 301 302 30m;
expires 30m;
proxy_pass http://127.0.0.1:8080;
}
}
location = / {
return 301 /myapp/;
}
location @maintenance {
root /opt/myapp/nginx/www;
rewrite ^ /maintenance.html break;
}
location @errors {
root /opt/myapp/nginx/www;
rewrite ^ /404.html break;
}
}
Este es el núcleo del sistema. Nginx maneja SSL, reenvía el tráfico a Tomcat, sirve la página de mantenimiento cuando Tomcat está fuera de línea, almacena en caché contenido estático y protege la disposición de la red interna.
Redirección HTTP (Puerto 80)
Agregué una configuración simple que redirige todo el tráfico HTTP a HTTPS.
/etc/nginx/sites-available/myapp_http
server {
listen 80;
server_name finance.example.com;
return 301 https://$host$request_uri;
}
Estructura de carpetas
Mantengo los archivos relacionados con Nginx dentro de una carpeta de aplicación dedicada:
/opt/myapp/
keystore/
nginx/
logs/
www/
Esto facilita la gestión de certificados, registros y páginas estáticas.
Configuración de Tomcat que completa la configuración
Dentro de server.xml de Tomcat, enlazo Tomcat a localhost para que no pueda ser accedido desde el exterior.
<Connector port="8080"
address="127.0.0.1"
maxHttpHeaderSize="65536"
protocol="HTTP/1.1"
connectionTimeout="20000"
maxThreads="150"/>
También hago que Tomcat entienda la IP real del cliente y el protocolo:
<Valve className="org.apache.catalina.valves.RemoteIpValve"
remoteIpHeader="X-Forwarded-For"
protocolHeader="X-Forwarded-Proto"
protocolHeaderHttpsValue="https"/>
Esto asegura que el sistema registre la IP correcta del cliente y se comporte correctamente para HTTPS.
Por qué esta configuración funciona bien para un sistema financiero
Colocar Nginx frente a Tomcat ha hecho que todo el sistema se sienta mucho más profesional y estable. Durante despliegues o reinicios, los usuarios nunca se encuentran con las típicas páginas 503 de Tomcat. En su lugar, siempre ven una pantalla de mantenimiento limpia, lo que hace que el sistema se vea confiable incluso cuando se está trabajando tras bambalinas.
Manejar SSL en Nginx también simplifica todo. Los certificados son más fáciles de gestionar, renovar y depurar, y Tomcat ya no tiene que lidiar directamente con HTTPS. Otro beneficio es la seguridad. Dado que Tomcat solo escucha en localhost, está completamente oculto del tráfico exterior, lo que elimina toda una categoría de intentos de escaneo y sondeo.
El rendimiento también mejora. Los archivos estáticos como CSS y JavaScript se cargan más rápido porque Nginx puede almacenarlos en caché, y las subidas se verifican y limitan antes de que lleguen a Tomcat. Algunas de nuestras operaciones financieras implican encabezados grandes o acciones de larga duración, y Nginx me da control total sobre los tamaños de búfer y los timeouts, lo que hace que estas operaciones se ejecuten sin problemas y sin errores aleatorios.
Incluso en los casos en que Tomcat se desconecta por un momento, el sitio sigue respondiendo de manera predecible gracias a la página de mantenimiento. A lo largo de los años, esta configuración ha demostrado ser extremadamente sólida. Ha ayudado a la aplicación financiera a lograr casi cero tiempo de inactividad a través de muchos lanzamientos y cambios de infraestructura, y sigue manejando el tráfico de producción sin sorpresas.