El proceso mencionado aqui tomó cuatro horas aprox.
Costo? Como anoté en las tres primeras partes esto fue un encargo para cliente. Desde el momento enb que entré a terminal en máquina limpia, hasta que cloné en la parte 5 fueron poco menos de tres días y no dedicados a esto..
La eficiencia técnica se traduce directamente en agilidad económica: mientras que el costo operativo de este stack en Vultr es de apenas 20 USD al mes, el proceso completo de implementación, desde el inicio de la configuración hasta la generación y clonación de la imagen final para el cliente, representó un gasto ínfimo de tan solo 2.33 USD. Esta cifra no solo cubre el tiempo de cómputo, sino también la transferencia de datos entre servidores durante el despliegue de la imagen maestra.
Es la prueba de que un servidor de alta densidad, basado en Debian 13 y optimizado quirúrgicamente, permite realizar despliegues masivos y entregas de infraestructura crítica por una fracción del costo de los proveedores tradicionales. No es solo gastar menos, es la capacidad de replicar entornos profesionales de producción en cuestión de minutos y por el precio de un café, manteniendo la soberanía total sobre el sistema y los datos del cliente.
El día de hoy terminaré de instalar este servidor Apache (LAMP) al tiempo que actualizo en otro ya existente, los tres sobre Debian 13. Hay una relación importante entre la memoria y el consumo de ella, y por qué usar Gitea. Joel Spolsky, antiguo programador de Microsoft, hablaba de las doce preguntas y una de ellas tenía que ver con builds / compilaciones de un solo paso. Creo que una vez establecido el front end (en este caso React) no necesitas hacerle muchos cambios, pero sí es común que establezcas nuevas funcionalidades «bajo el capó», en backend, que no se ven. Y en eso Quarkus brilla. Además, usa mucho menos memoria que Spring Boot.
Sin embargo, tengo que hacer una reflexión personal. Casi siempre mi trabajo ha sido arreglar desastres. A veces programando de cero, a veces dando mantenimiento a cosas indescriptibles. He visto consumos gigantescos de hosts que no servían, incluyendo transas de las personas de sistemas. Tecnologías corruptas o mal empleadas.
Usando una metáfora, yo no necesito un iPhone. Uso un teléfono Motorola G31 de unos 150 USD. La principal razón es porque tiene el encendido por huella dactilar, sin presionar botón lateral. Un iPhone o iPad solo me interesaría por las fotos de alta calidad, por documentos de juzgados.
Sin embargo, a nadie lo corrían hace años por contratar IBM. Ahora es algo parecido con Azure y AWS. Principalmente en entorno Azure he visto que universidades públicas reciben dinero para promover Azure y sus recién egresados piensan que es lo único. Usando una metáfora… no todos necesitan un Samsung de alta gama o un iPhone. Lo mismo pasa con Azure y AWS.
En este entendido, a veces el presupuesto o vivir en la punta del cerro, aunque puedas y lo quieras, te complican muchísimo comprar un teléfono de alta gama. Y para estar con línea de cobre, sin línea óptica. Otro ejemplo sería que salir con un billete de 1000 MXN a la calle es como traer nada, porque cambiarlo o que te lo acepten es difícil, y debe ser horrible salir a la calle con 3000 pesos en monedas de a peso. Como dato particular, en viajes a la playa solía usar una bolsa agarrable a la pierna, llena de monedas de 10 pesos, el equivalente de 3000 MXN, y se podía mojar.
Muchos de tus clientes de correo o de host son personas que usan pocos recursos. No falta la princesa o el princeso que si no es iPhone 25 no te mira a los ojos. Pues yo creo que salir a la calle con billetes de 100 y 200 te da movilidad. Se trata de resolver un problema, y Quarkus es maravilloso en eso. Pero si sumas su bajo consumo de memoria con relación a Spring Boot, te encuentras con la facilidad de implementación que hablaba Spolsky. Y eso solo te lo da en Web React / Quarkus, o PHP puro.
Pero en este caso el cliente quiere Springboot.
Asi que empecemos:
Ojo con dos errores comunes por ser wordpress este texto, y lo puse en letras grandes para que no haya duda.
-
Las Comillas: Al copiar y pegar en editores como WordPress, las comillas rectas » a veces se convierten en curvas “. Asegúrate de que en los bloques de código (especialmente el de Java y Nginx) se mantengan las comillas rectas, o el compilador dará error.
- Permisos de Ejecución: En la parte donde creas el servicio systemd, debes asegurarte de que el archivo mvnw tenga permisos de ejecución (chmod +x mvnw). Es un detalle que a veces olvidamos.
Los 3 puntos clave de hoy para Gitea:
- Proxy Inverso (Apache): Despedirnos del puerto 3000 para entrar por git.tu-dominio.com.
- SSL Final: Extender el certificado de Certbot para que el subdominio de Gitea y la ruta /app/ de React sean inexpugnables.
- Ajuste del app.ini: Configurar internamente a Gitea para que reconozca su nueva identidad HTTPS y cerrar el puerto en el firewall.
Es como poner carrocería y blindaje al servidor. Digamos que es un hardening de nivel medio.
En lugar de entrar por una subcarpeta, vamos a darle su propia identidad: git.tu-dominio.com.
Empezamos !!!
Verificamos que este instalada la opcion de Proxy.
-
- a2enmod proxy
- a2enmod proxy_http
- systemctl restart apache2
Primero, crea el archivo de VirtualHost para el subdominio:
nano /etc/apache2/sites-available/git.tu-dominio.com.conf
Y como contenido:
<VirtualHost *:80>
ServerName git.tu-dominio.com
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:3000/
ProxyPassReverse / http://127.0.0.1:3000/
ErrorLog ${APACHE_LOG_DIR}/gitea-error.log
CustomLog ${APACHE_LOG_DIR}/gitea-access.log combined
</VirtualHost>
Habilitamos el sitio: a2ensite git.tu-dominio.com.conf && systemctl restart apache2
Pero ahora hay que decirle a certbot que cree un certificado.
-
certbot --apache -d git.tu-dominio.comCon un f5 ya se debe de ver con candado de certificado (en mis tres casos si)
Si no entra probablementees porque no tienes debian 13.
Si Certbot te pregunta si quieres «Redirigir» (Redirect), dile que SÍ (opción 2). Esto insertará automáticamente las reglas necesarias para que cualquier intento de entrar por HTTP salte a HTTPS.
2. Verificar el archivo generado
Una vez que Certbot termine, debería haber creado un archivo nuevo en
/etc/apache2/sites-available/git.tu-dominio.com-le-ssl.conf.Si entras y sigue sin cargar, revisa que ese nuevo archivo tenga las líneas del Proxy, porque a veces Certbot solo copia lo básico. El archivo debería verse así:
Apache
<IfModule mod_ssl.c> <VirtualHost *:443> ServerName git.tu-dominio.com ProxyPreserveHost On ProxyPass / http://127.0.0.1:3000/ ProxyPassReverse / http://127.0.0.1:3000/ # Las líneas de los certificados (que pone Certbot) SSLCertificateFile /etc/letsencrypt/live/git.tu-dominio.com/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/git.tu-dominio.com/privkey.pem Include /etc/letsencrypt/options-ssl-apache.conf </VirtualHost> </IfModule>
3. ¿Por qué podría seguir fallando? (Checklist de purga)
DNS: ¿El subdominio
gitya apunta a la IP de tu servidor? (Si el ping agit.tu-dominio.comno responde, Certbot fallará).A2ensite: Si Certbot creó el archivo pero no lo activó:
a2ensite git.tu-dominio.com-le-ssl.confsystemctl restart apache2Firewall: Recuerda que ahora entramos por el 443. Asegúrate de que UFW lo permita:
ufw allow https
Si ya quedó falt algo importante.
Cerrar el puerto 3000
- #Falta este paso crucial:
- ufw delete allow 3000/tcp
- ufw reload # Agregar esto
Estaremos listos para instalar Java 21 y Spring Boot.
Primero, recordemos que es una LTS.
Como dije instalaremos una versión LTS (Long Term Support). En Debian 13, la opción más robusta y compatible con las versiones modernas de Spring Boot 3.x es Java 21.
nano /var/www/tu-dominio.com/public_html/monitoreo.php
Pega el siguiente código (quiza mejor si lo pegas en un notepad primero y sin espacios al principio ….):
Debe quedar claro que a veces los servidores tienen cosas cerradas. Asi quye te voy a poner dos opciones:
<?php
// Obtener datos de memoria desde /proc/meminfo o el comando free
$free = shell_exec('free -m');
$free_lines = explode("\n", trim($free));
$mem_info = preg_split('/\s+/', $free_lines[1]);
$total_mem = $mem_info[1];
$used_mem = $mem_info[2];
$percent_mem = round(($used_mem / $total_mem) * 100, 2);
// Obtener datos de disco
$disk_total = disk_total_space("/") / 1024 / 1024 / 1024; // GB
$disk_free = disk_free_space("/") / 1024 / 1024 / 1024; // GB
$disk_used = $disk_total - $disk_free;
$percent_disk = round(($disk_used / $disk_total) * 100, 2);
echo "<h2>Estado del Servidor (Debian 13)</h2>";
echo "<b>Memoria RAM:</b> $used_mem MB usados de $total_mem MB ($percent_mem%)<br>";
echo "<div style='width:300px; background:#ddd;'><div style='width:$percent_mem%; background:red; height:10px;'></div></div>";
echo "<br><b>Disco Duro:</b> " . round($disk_used, 2) . " GB usados de " . round($disk_total, 2) . " GB ($percent_disk%)<br>";
echo "<div style='width:300px; background:#ddd;'><div style='width:$percent_disk%; background:blue; height:10px;'></div></div>";
echo "<br><b>Carga de CPU (1, 5, 15 min):</b> " . implode(", ", sys_getloadavg());
?>
Opcion 2 :
- nano /var/www/tu-dominio.com/public_html/monitoreoaoa2.php
<?php
// Habilitar errores para ver qué pasa si falla
ini_set(‘display_errors’, 1);
error_reporting(E_ALL);function get_server_memory_usage(){
$free = shell_exec(‘free’);
if(!$free) return «Error: No se pudo ejecutar ‘free’.»;
$free = (string)trim($free);
$free_arr = explode(«\n», $free);
$mem = explode(» «, $free_arr[1]);
$mem = array_filter($mem);
$mem = array_merge($mem);
$memory_usage = $mem[2] / $mem[1] * 100;
return array(‘total’ => $mem[1], ‘used’ => $mem[2], ‘percent’ => round($memory_usage,2));
}$mem = get_server_memory_usage();
echo «<h3>Uso de RAM: » . $mem[‘percent’] . «%</h3>»;
?>Eso me dio la opcion uno y la segunda un texto de 18% libre
Creo que ahora puees ver porqué puedo correr muchísimas cosas en servidores de 1 a 2 GB de ram, en php puro, aunque sean para 20-30 usuarios simultáneos.
Mantenimiento: La regla de oro antes de la batalla
Antes de meter el motor de Spring Boot en la siguiente entrega, hay que asegurarse de que los cimientos estén firmes. Instalar Gitea, configurar Proxies y mover Certbot genera movimiento en los repositorios. Un buen administrador no deja basura atrás.
Corremos una actualización final para consolidar los parches de seguridad de los módulos de Apache y las librerías de SSL que acabamos de configurar:
- apt update && apt upgrade -y
Y para mantener ese 19% de RAM y el disco limpio, eliminamos cualquier residuo de paquetes que ya no sea necesario tras nuestras configuraciones:
- apt autoremove -y
- apt autoclean
En mi caso solo el servidor que venía de debian 11 hizo cambios quitando paquetes.
Hasta aquí es lo que llego hago normalmente en mis servidores PROPIOS y a veces ni les instalo Gitea.
Despliegue de Spring Boot, parte Uno.
EL mejor ejemplo que se me ocurre aquí es que de repente le puedes pedir a tu hija que vaya a la tienda, o a un compañero que saque una copia o un respaldo. Si eres profesional lo revisas despues porque no puedes hacer desayuno sin ir a la tienda, ni el tramnite sin la copia. (y por cierto que no sirev de nada si dejas el documento en casa o es del documento equivocado)
Parte 3.1 : El Despliegue de Spring Boot (JDK 21)
1. Instalación del Motor (JDK 21)
Primero, instalamos el entorno de ejecución para Java. Usamos la versión 21 por ser la LTS actual y necesaria para Spring Boot 3.
- apt update
- apt install openjdk-21-jdk -y
- # Verificamos la instalación
- java -version
2. Preparación del Directorio de Trabajo
- No debemos correr el backend como root. Usaremos /var/www para mantener la estructura de Apache.
Bash
- mkdir -p /var/www/backups_java
- # Le damos la propiedad al usuario del servidor web
- chown www-data:www-data /var/www/backups_java
- chmod 755 /var/www/backups_java
3. El Script de Lanzamiento (El «Limitador de RAM»)
Para que Spring Boot no se «coma» todo el servidor (manteniendo nuestra filosofía de ahorro), crearemos un pequeño script de arranque que limite la memoria.
nano /var/www/backups_java/start.sh
Teb cuidado que no hayan espacios en blanco al inicio del archivo o en un primer renglon.
#!/bin/bash
# Limitamos a 512MB de RAM máxima para mantener la movilidad
java -Xms256M -Xmx512M -jar /var/www/backups_java/tu-proyecto.jar
No olvides el permiso de ejecución:
- chmod +x /var/www/backups_java/start.sh
4. Creación del Servicio Inmortal (Systemd)
Para que el backend inicie solo con el servidor y se reinicie si falla.
- nano /etc/systemd/system/spring-app.service
y pones dentro
[Unit]
Description=Backend Spring Boot
After=syslog.target network.target mariadb.service[Service]
User=www-data
WorkingDirectory=/var/www/backups_java
ExecStart=/var/www/backups_java/start.sh
SuccessExitStatus=143
Restart=always
RestartSec=10[Install]
WantedBy=multi-user.target
Despues de eso …
- # Recargar systemd para que reconozca el nuevo servicio
- systemctl daemon-reload
- # Habilitar para que inicie con el servidor y arrancarlo ahora
- systemctl enable spring-app
- systemctl start spring-app
5. El Puente en Apache (Proxy para la API)
Finalmente, le decimos a Apache que todo lo que llegue a tu-dominio.com/api lo mande al motor de Spring Boot (puerto 8080).
Edita tu archivo de VirtualHost SSL existente:
- nano /etc/apache2/sites-available/tu-dominio.com-le-ssl.conf
Agrega estas líneas antes del cierre de </VirtualHost>:
# Proxy para el Backend de Spring Boot
ProxyPass /api http://127.0.0.1:8080/api
ProxyPassReverse /api http://127.0.0.1:8080/api
6 Ahora verificamos :
apache2ctl configtest
debe darte syntax ok
Vamos a probar : URL Qué debe mostrar Archivo que lo controla
- tu-dominio.com tu prueba que hiciste o el mismo monitoreo done lo hayas puesto.
- tu-dominio.com/app/ El React (Front) tu-dominio.com-le-ssl.conf (por eso es el app en virtualhost)
- git.tu-dominio.com El Gitea (Repos) git.tu-dominio.com-le-ssl.conf
- tu-dominio.com/api Error 503 (por ahora) El bloque Proxy que añadiremos
7 Ahora nos preparamos para el hola mundo en spring :
Nota: debe de estar corriendo cada diez segundos tratando de lanzar el rpoyecto que mencionamso que todavia no existe. asi que …
7.1. Crear el código fuente de prueba
Vamos a crear un servidor web básico en un solo archivo Java dentro de tu carpeta de trabajo:
nano /var/www/backups_java/TestServer.java
Pega este código (es Java 21 estándar, no requiere librerías externas):
/* Prueba en java 21 */
import com.sun.net.httpserver.HttpServer;
import java.io.OutputStream;
import java.net.InetSocketAddress;
public class TestServer {
public static void main(String[] args) throws Exception {
HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0);
server.createContext("/api", (exchange) -> {
String response = "<h1>Backend Skeleton: OK</h1><p>Conectado exitosamente via Apache Proxy</p>";
exchange.sendResponseHeaders(200, response.length());
OutputStream os = exchange.getResponseBody();
os.write(response.getBytes());
os.close();
});
System.out.println("Servidor de prueba iniciado en el puerto 8080...");
server.setExecutor(null);
server.start();
}
}
Paso 7.2: Compila y genera el JAR:
cd /var/www/backups_java/
javac TestServer.java
# Creamos el JAR con el punto de entrada en TestServer
jar cfe tu-proyecto.jar TestServer TestServer.class
Paso 7.3 Permisos y Arranque:
- chown www-data:www-data tu-proyecto.jar
- systemctl restart spring-app
Paso 7.4
Desde terminal o bash
- #prueba 1
- journalctl -u spring-app -f # te debe mosttar servidor de prueba iniciado en el puerto 8080
- #Prueba 2
- curl -v http://127.0.0.1:8080/api
-
y https://tu-dominio.com/api/
si la tres no queda…. edita el archivo le-ssl de tu dominio que esta en /etc/apache2/sites-available/
y que qudee asi … las /api/ son importantes la barra, es una forma de forzar a apache a hacer que hagas lo que quieres y si te fijas cambiamos el orden tambien.
<IfModule mod_ssl.c>
<VirtualHost _default_:443>
ServerName tu-dominio.com
ServerAlias www.tu-dominio.com
ServerAdmin tumail@gmail.com# Proxy para el Backend de Spring Boot
ProxyPreserveHost On
ProxyPass /api/ http://127.0.0.1:8080/api
ProxyPassReverse /api/ http://127.0.0.1:8080/api# Apuntamos a la vitrina real
DocumentRoot /var/www/tu-dominio.com/public_html<Directory /var/www/tu-dominio.com/public_html>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory># El motor de React
<Directory /var/www/tu-dominio.com/public_html/app>
RewriteEngine On
RewriteBase /app/
RewriteRule ^index\.html$ – [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /app/index.html [L]
</Directory>ErrorLog ${APACHE_LOG_DIR}/tu-dominio-error.log
CustomLog ${APACHE_LOG_DIR}/tu-dominio-access.log combinedInclude /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/tu-dominio.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/tu-dominio.com/privkey.pem
</VirtualHost>
</IfModule>
Y luego otra vez
- # 1. Asegura que los módulos estén activos (por si acaso)
- a2enmod proxy proxy_http
- # 2. Verifica que no haya errores de dedo en el archivo
- apache2ctl configtest
- # 3. Reinicia Apache para que lea la nueva prioridad
- systemctl restart apache2
Ahora si …
- https://tu-dominio.com/api/
La diagonal es importante y debes ver …
Backend Skeleton: OK
Conectado exitosamente via Apache Proxy
¿Por qué funcionará ahora?
Al poner el Proxy antes del DocumentRoot, le dices a Apache: «Antes de que busques archivos en la carpeta public_html, si ves que la dirección empieza con /api, mándala directo a Java».
En Apache, omitir una diagonal es la diferencia entre que el servidor busque un archivo o que entienda que es un puente hacia otro servicio. No es capricho, es sintaxis.
Finalmente :
https://tu-dominio.com/monitoreo.php
Como puedes ver los numeros son excelentes. Lo que pesa es el codigo, y la mezcla de tres modos diferentes de usar Spring Boot. Debes tratar de unificarlo en uno solo. Yo prefiero JDBC pero hibernate / JPA tiene sus ventajas.
Vamos a comparar los dos graficos.
Antes de Spring
Despues de spring
En realidad estas usando menos de 40 MB mas.
8.- Check list
- # ========================================
# CHECKLIST FINAL – PARTE 2 COMPLETA
# ======================================== - # Gitea en subdominio con SSL
curl -I https://git.tu-dominio.com | grep «200 OK» - # Puerto 3000 cerrado externamente
nmap -p 3000 $(curl -s ifconfig.me) # Debe dar «filtered» o «closed» - # Java 21 instalado
java -version | grep «openjdk version \»21» - # Skeleton respondiendo
curl https://tu-dominio.com/api/ | grep «Backend Skeleton» - # Memoria bajo control
- free -m | awk ‘NR==2{printf «RAM: %s/%sMB (%.2f%%)\n», $3,$2,$3*100/$2 }’
free -m | awk ‘NR==2{printf «RAM: %s/%sMB (%.2f%%)\n», $3,$2,$3*100/$2 }’
# Debe mostrar ~788-820 MB de 4096 MB (~20%) -
(Asegúrate de que las comillas simples son rectas en WordPress. Las centrales son dobles chr(34))# Servicio
-
spring-app activo
systemctl is-active spring-app # Debe decir «active» - # Logs sin errores críticos
journalctl -u spring-app –since «10 minutes ago» | grep -i «error»
Cual es el problema REAL ?
Que no tienes instalado así en tus servers de producción. Solo una personao varias que hicieron lo que buenamente podían.
Un servidor es tan bueno como su admin
Cual es mi preocupación moderna ?
Tenemos un hola mundo que usa 788 mb de ram y tres o cuatro horas de un devops experto para configurar.
Y cuando llegan los programadores… mezclan los estandares y hay errores de diseño.
Usando metáforas… hay coches automáticos y hay coches estandard. También algunos tienen diferente el cambio de velocidades. Algunos a 50 otros a 60 kms Pero debe haber un estandard de los programadores para no dañar la maquinaria. De nada sirve tener un motor afinado si el conductor no sabe meter las velocidades y que es criminal en un automático pisar a la vez el freno y el acelearador. Con lo que yo hice, no necesitas meter el clutch. Solo no hacer barbaridades.
o con mi sinceridad habitual: Los programadores mezclan los estándares y hay errores de diseño… De nada sirve tener un motor afinado si el conductor no sabe meter las velocidades
El Problema Real del Spring Boot Salvaje:
- Equipos mezclan JDBC, JPA e Hibernate sin estrategia
- Configuraciones copiadas de Stack Overflow sin entender
- Pools de conexiones sin límites → RAM explota
@Autowireden todos lados → código imposible de testear
Mañana veremos cómo implementar un carrito de compras en Spring Boot manteniendo esta disciplina de diseño y sin react
Notas Técnicas importantes
En el ejemplo que puse Script start.sh tiene ruta hardcodeada
bash#!/bin/bash
# Problema: «tu-proyecto.jar» es placeholder
java -Xms256M -Xmx512M -jar /var/www/backups_java/tu-proyecto.jar
# Mejor:
java -Xms256M -Xmx512M -jar /var/www/backups_java/TestServer.jar
O mejor aún, usar variable:
bash#!/bin/bash
JAR_FILE=»TestServer.jar»
java -Xms256M -Xmx512M -jar /var/www/backups_java/$JAR_FILE
5. Advertencia sobre com.sun.net.httpserver
El código Java usa com.sun.net.httpserver, que es parte del JDK pero no es API oficial.
Explicación: Este servidor usa com.sun.net.httpserver, que viene con el JDK pero no es recomendado para producción. Es perfecto para esta prueba de concepto, pero en producción usarías Spring Boot con @RestController.
Porque ?
Hay tres opciones Basicas ademas de esto.
- Mi opción por lo general es usar gradle si tengo que usar springboot
- crear un proyecto de maven minimo, de memoria mkdir -p /var/www/backups_java/spring-simple/src/main/java/com/demo
cd /var/www/backups_java/spring-simple y luego el pom.xml y las clase principal
y compilar - la tercera opcion es la recomendada: Spring Boot con Spring Initializr
- Paso 1: Crear el proyecto base
- bashcd /var/www/backups_java/
- # Descargar un proyecto base de Spring Boot desde start.spring.io
- curl https://start.spring.io/starter.zip \
- -d dependencies=web \
- -d type=maven-project \
- -d language=java \
- -d bootVersion=3.2.1 \
- -d baseDir=demo \
- -d groupId=com.tudominio \
- -d artifactId=backend-api \
- -d name=BackendAPI \
- -d packageName=com.tudominio.api \
- -d javaVersion=21 \
- -o backend-api.zipunzip backend-api.zip
cd demo
y crear un controlador simple y archivos de application compilando eejcutando y actualizando el script de inicio.
Porque lo hice asi ?
Uy.
Aunque suene a texto de programador sufrido, no quiero que digas palabrotas al ver lo necesario para inicializar una version correcta de spring si solo has visto el frontend y no has instalado. No se a cual de las tribus de spring perteneces tu lector JDBC , JPA / HPA ni que entiendes por Spring Security y que usas. Mis primeras dos semanas revisando un proyecto de java es ver que dicen los desarrolladores que es el spring security y el stack que estan usando. Es como cuando preguntas que versión de sistema operativo usas y te dicen linux o windows, no te sirve de nada.
Las Tres Tribus de Spring Boot
Cuando pregunto «¿qué stack de Spring usas?», las respuestas varían:
1. Tribu JDBC: Spring Boot + JDBC Template (el más ligero, ~120 MB)
2. Tribu JPA/Hibernate: Spring Data JPA (el estándar, ~180 MB)
3. Tribu Mixta: JDBC para lectura + JPA para escritura (el caos, ~200 MB)
( y te pueden responder groseramente dimelo tu, ya deberías saberlo, sabes o no sabes … o candidamente el de linux o el de siempre)
El problema: Cada tribu tiene su propia configuración de pools de conexión,
transacciones y cache. Mezclarlas sin estrategia es como tener 3 volantes en un auto.
A veces, para diagnosticar un puente, no necesitas un tráiler de 18 ejes (Spring Boot); necesitas una bicicleta para cruzar y ver si el pavimento aguanta. El Skeleton en Java puro es esa bicicleta.
Como lei en un libro : Si no sabes qué versión de Spring Security usas, no tienes seguridad, tienes una puerta cerrada de la que perdiste la llave.
- Los cambios de versión a 7 fueron brutales. Lo que encuentras actualemente es una mescolanza desfasada, y piensan que eso los vaa proteger de los problemas mas comunes de seguridad… Y por lo general no ysan jackson, y por lo mismo no entienden lasdiferencias de jackson2 a jackson3 y sus implicaciones en seguridad.
- Mi respuesta es super simple. «Te entiendo perfectamente. Te sugiero que pongas un token JWT y queda un poco mas claro»
- Explicación: JWT hace lo mismo, mas rápido, sin cambios de versiónes, estandard internacional y una vez que tienes eso puedes empezar a entender a que llaman en ese lugar y proyecto «spring security»
- Tienes que preveer contingencias legales. Equipo rojo. Doble ciego. Si usas datosconfidenciales mas. Para eso es jackson 2 y jackson 3 necesario.
Comentario experto :
El problema del @Autowired es que se ha convertido en la «droga» de los desarrolladores modernos: inyectan cosas sin saber qué están inyectando, quién las creó ni cuánta memoria están consumiendo. Es programación por «acto de fe». Un programador que solo sabe usar
@Autowiredno es un arquitecto, es un ensamblador de piezas que no comprende. Los cambios de manejo de fechas cambian en jackson 2 a 3 y la visibilidad de campos personales afecta tu compliance con la ley, pero eso si obtienes vectores de ataque llamado /metrics /env /heapdump muy bonitos. (informas la memoria RAM a cualquiera que sepa la URL por defecto.) Actuators =/ Compliance incluso Actuators <> Compliance incluso sin 853 paquetes de dependencias no auditables.
Cuando mencionas Jackson, tocas el nervio expuesto. La mayoría no entiende que Spring Boot no es magia, sino una serie de librerías trabajando juntas. No saben que si Jackson está mal configurado, su API es vulnerable a ataques de deserialización o que están enviando más información de la cuenta en el JSON porque no saben usar un @JsonView o un DTO.
Un resumen de porque no usar Springboot, para mi, en proyectos con datos sensibles y mucho menos cuando el software es el activo principal de la empresa.
- Si vas a usar el tráiler de 18 ejes (Spring Boot), tienes que saber manejar Jackson y cerrar Actuators; si no sabes, mejor quédate en el LAMP (camioneta), donde el control es manual, directo y no hay ‘magia’ que te abra puertos por la espalda.
- Un activo que nadie entiende (3,000 archivos de Spring/React con dependencias desconocidas) tiene menos valor real que un sistema auditable, compacto y documentado.
- No puedes confiar el corazón del negocio a una serie de librerías (como Jackson) que no sabes configurar. Si no sabes configurarla o no sabes que existe, no dominas la herramienta, no eres dueño de tu activo; eres un rehén de la complejidad que trae mas problemas que beneficios.
- En estos casos la sobrevivencia depende de la suerte, de tu proveedor, y que no haya un equipo rojo ni daños en tus respaldos. No de los programadores.
- ¿quien eligió el stack? Pregunta Sobre jackson. Si no te sabe responder cambia de persona y de Stack YA.
Lo que hice yo al usar com.sun no es soportado oficialmente 100% pero está en el 95% de los servidores, tiene threading limitado, el json es manual, no tiene spring security (que a veces es una ventaja porque cambia de una versión a otra) la gestion de errores es manual y con system.out no tienes health checks pero usas 30 mb en lugar de 120 mb
Y muchas veces lo que me funciona, pero sabiendo lo que estoy haciendo es quitar spring security y usar com.sun.net.httpserver. En lo que arreglo el lio. La mayor parte de los sistemas reales de empresas medianas en méexico tienen en media noche usuarios cero así que puedes hacer revisiones en la madrugada con un .com.sun temporal

