Checklists de Prompts Inteligencia Artificial

Hace unos 35 años empecé a usar un método de control de prioridades, llamado «Administración por objetivos». Que yo recuerde, el creador es Drucker antes que yo naciera, mediados de los 50s. En algunos libros vi puntos de referencia y en los 80s salieron varios libros más que llegaron a México cuando ya eran principios conocidos.

Por ejemplo, yo las usaba desde los 80s para mi vida personal, y cuando empecé a trabajar en 1991, usé APO para dar soluciones, sobre objetivos realistas u útiles, pero no arbitrarios.

Pues resulta que hace rato me puse a leer un libro sobre Inteligencia Artificial que escribió un cliente mío. No doy el nombre porque los de la secta (una que me atacó durante años y que seguro me lee de repente después de su oso) podrían atacarlo, pero el caso es que era un libro sobre Inteligencia Artificial y sus usos para usar experiencia propia, sumado a enfoque de IA e iteraciones. En lo personal es un uso de sentido común.

Además de la parte sobre ética, y que me consta que yo lo introduje a Claude LLM al cliente hace unos meses, el enfoque hizo el libro fácil de leer. Pero lo que me llamó mucho la atención era un checklist de cómo realizar consultas «prompt» a la IA. Sí, parece que son de sentido común pero para mí los elementos son evidentes si conoces APO y nunca se me habría ocurrido formalizarlo de este modo específico para prompts de IA. Su checklist es excelente.

Solo puse una mejora: constraints o reglas, es decir, limitaciones de lo que puedes o no puedes hacer de manera ética o financiera. Y eso el autor del libro lo menciona como de pasada en la parte de ética, pero es una guía muy buena.

Checklist de elaboración de Prompts para IA.

  • Tarea clara
  • Contexto Relevante
  • Ejemplo o modelo
    • Constraints o reglas – independientes del Contexto
  • Persona Asumida (Rol o Punto de vista)
  • Tono deseado
  • Formato Específico (lista tabla, esquema pasos)

Los problemas de la memoria en producción

He comentado que recientemente me buscaron de una startup con problemas. No para ofrecerme un puesto, sino para dar una plática. Que tienen ciertos problemas, sí. Y ciertos es poco. Solo con saber la estructura es suficiente.

Me llamaron por recomendación de dos personas con las que he trabajado: uno de los administradores de dinero y uno de los desarrolladores. Tienen unas siete personas en desarrollo que yo haya visto. Tienen stacks PHP, Hibernate, parte JDBC (creo) y unas cosas en Python. Y para ellos una instancia MÍNIMA es de 8 GB.

Además, tuvieron un problema fenomenal que les resolví hace como dos meses y medio, que era un Snap o atajo de Ubuntu. Yo les comenté entonces que era mejor migrar a Debian 13 o AlmaLinux. Pero por detalles técnicos, lo mejor es una de las distribuciones básicas de Linux, y por eso estamos hablando aquí de Debian. Ya no tengo ninguna otra distro en los propios, pero un cliente tiene un AlmaLinux.

Tiene sentido. Por lo que me dijeron estudiantes del IPN y de la UNAM el año pasado, en servicio social, les dan 8 GB de su tiempo gratis u horarios gratis. Y los servidores Linux de gobierno que manejé el año pasado eran de 8 GB de RAM infame bajo Azure, Rocky Linux y Red Hat sin root.

Solo que los costos de respaldo de Amazon son un problema real. ¿Solución? No respaldan. Por lo que sé, decidieron pedirme dar la plática después de la última caída de la zona principal de Amazon, us-east-1.

Mi primera computadora en 1991 tenía 1 MB de RAM. Al terminar el año creo que tenía seis computadoras. Algunas de 512 y 640 KB, no estoy seguro. Pero aprendí a respetar la RAM y los procesadores.

Revisando costos en este momento, sabiendo lo que haces y sabiendo levantar tu servidor en VPS unmanaged, estos son los costos a 5 de enero de 2026.

Nota: Estoy seguro de que hace dos o tres semanas busqué suempresa.com, que era un proveedor mexicano, y primero pensé que ya había desaparecido. Un punto a favor de por qué no usar proveedores mexicanos. Resulta que no; hicieron un rediseño tan malo que pensé que era una parking page o «se vende este dominio». No lo recomiendo, pero pongo ejemplos aquí.

Voy a calcular costos de 8 y 4 GB de RAM con alrededor de 60 a 80 GB de disco duro con proveedores en México:

  • Suempresa.com: 600 pesos mensuales pagando tres años por anticipado, más IVA por 4 GB de RAM y 80 de disco duro. Por 800 más IVA mensuales, y solo AlmaLinux. Lo descarto porque es mejor pagar mes por mes por si cambia la calidad y porque requiero Debian 13.

  • Neubox.com: 1090 al mes más IVA = 1264 en lo que llaman opción C, sin haber opción B, con 6 GB y 192 de disco duro, con Debian 12 como opción, pero tres nuevas opciones de servidores que son marketing. Veo varios problemas, principalmente porque el espacio se excede de lo razonable. Si estuvieran usando RAID 5 o RAID 0, tendrían que ofrecer menos disco duro. Suena razonable, pero no, gracias; y no voy a tratar de entender las otras dos opciones de servidores.

  • Hostinger.com.mx: Dice tener VPS manejados por IA, por costo que bajó de 315 MXN a 136 MXN mensuales a 8 GB RAM con 100 GB de espacio en disco NVMe. Demasiado barato. Deben sobrevender y tener servidores saturados.

Explico: no puedes poner la supervivencia de tu empleador, de tu trabajo o tu reputación profesional en proveedores que no cuentan con reseñas internacionales. Por «reseñas internacionales» y un sitio de referencia que uso, solo usaría Hostinger, pero los precios son… simplemente… raros. Sobrevenden. Supongo que por esto muchos se van a Amazon, Azure o Google Cloud.

Ahora viene el momento de espantarnos. En términos de «servidores de alguien más» o nube, estos son los equivalentes:

  • Google Cloud: Instancia n2, lo mínimo es 375 GB de disco duro, 8 GB de RAM, 101.90 USD mensuales y buena suerte con hablar con un humano. Hay descuentos por uso frecuente o continuado, pero esto te lo dan varios proveedores de USA con soporte técnico. La falta de soporte de Google Cloud es para mí un «no, no». Conozco tres proveedores por lo menos en USA, reconocidos internacionalmente, que te dan un poco menos de disco duro, pero te manejan el servidor. Esto simplemente es excesivo y en la instancia menor n1 o e2, que es un poco mayor, puedes ahorrarte 20 USD o subir a 336 USD mensuales solo en costos iniciales. Descartado por «no humanos».

  • Azure: Pues… siendo sinceros, vi un papel en la oficina de uno de los socios que me hace pensar que contrataron el paquete preconfigurado Cloud-native apps on Kubernetes. Mis cálculos eran de 900 USD al mes, pero ya viendo son 1077. 100 GB de egress, lo que significa que no puedes atender clientes y sacar respaldos. Configurando a mano la instancia simple es más simple o peor. Todo gratis el primer año si no te pasas de ciertos límites. Pero al tratar de ver que tienen sus Data Factory o el uso de SQL Server, a simple vista es muy poco para una solución de trabajo real como varias bases de datos que manejo en Debian de más de 18 GB de SQL en MariaDB : son simplemente inmanejables en costo. La mejor metáfora que se me ocurre es cuando vas a preguntar cuánto cuesta una casa o un coche y te dan como 80 respuestas de los accesorios, pero no cuánto cuesta la casa en efectivo más el pago del notario. Tengo la fuerte sospecha de que muchas personas que parecen ser «administradores» tienen uno de esos paquetes de Kubernetes, no tienen ni idea y rezan mucho. (Update: al pasarle a leer esto a mi conocido desarrollador, me dice que son tres paquetes Kubernetes. 60 mil pesos mensuales que él sepa. ¡Ay, Dios!).

  • Amazon (AWS): Para empezar, Amazon no te deja usar el estimador de precios hasta que creas una cuenta, y para continuar te cobran hasta por estornudar. Literalmente te cobran todo lo que no estaba contemplado allí, así que una vez que tienes tu presupuesto lo mejor es multiplicar por 1.3, y eso en el mejor de los casos. Uso a veces esta calculadora en línea: https://learnaws.io/aws-calculator/ec2. Pero en terminología AWS necesitas por lo menos instancia EC2 y un S3 porque no vas a usar Lightsail. Solo puedo decir que un estimado mínimo y conservador son 59 USD por la EC2 y una S3 de 4 USD; pero una vez que ves un Memcached de 120 USD, yo diría que por estimado conservador para 8 GB de RAM son 200 USD mensuales. Menos que Azure, pero con más puntos de error y menos tolerancia al descuido. Creo que varios casos han sido problemas donde el administrador no es precavido y los dueños lo ven como sabotaje o estupidez. Si usas taxi a diario o un Uber a diario vas a pagar mucho. Que te lo explican, sí, pero después de cada viaje.

    • Me han pagado dinero desde hace unos 7 años para traducir a español las facturas de AWS.

¡Qué horror, ¿no? Hay cuatro situaciones que quiero destacar:

  1. La mayor parte de los clientes medianos en México no pueden pagar esto. Y si pueden, mejor que te lo paguen a ti que a Azure o Amazon.

  2. No me meto a arreglar AWS o Azure ajenos. Si me pasan la responsabilidad, me deben dar una autoridad y eso es DINERO. No se necesita ser un genio para entender que si de servidores pagan 20 mil y no sirve, no necesitas una ronda de financiación de capital, sino reducir costos.

  3. El estándar en México paraprogramadores no .net, hace tres años era Laravel. Ahora Spring Boot y React, que en otros países van de salida ambos, pero llevamos siete años de atraso contra otros países.

  4. «Traigo mi iPhone 24 pero ya salió el 25, este trabajo no me paga lo suficiente» es el equivalente para un programador a «tenemos siete timoneles y un remero, hay que poner un timonel más para mejorar al remero».

    • El equivalente a nivel organizacional es: tenemos siete directores y un programador. Y la solución que proponen los directores para que el programador rinda más es poner un octavo director que lo supervise, en lugar de darle un servidor que no sea un pantano de Snaps y complejidad innecesaria.

Es menos peligroso para los directores meterle más dinero a la nube que aceptar que su estructura es basura. Y siendo sinceros, el principal problema es que no solo el hardware es excesivo, sino que usan un stack innecesario sobre código no optimizado. Lo resuelves con simplificaciones graduales. Pero empieza verificando cuántos usuarios reales tienes y cuántos hace un año; los bots de Google no cuentan.

Viendo este panorama, queda claro que el problema no es la falta de dinero, sino el gasto de dinero a lo tonto y el exceso de complejidad. Voy a demostrarles que podemos tener control, respaldos y rendimiento con Debian 13 en una instancia de 4 GB, gastando menos de lo que Azure cobra por un simple error de configuración.

¿Cuál es el problema? Si te va bien, tienen dinero en el trabajo para meter en Amazon como escudo de impunidad para los directores. Y si quieres hacer respaldos te van a regañar. Y no falta quien quiere pagar 1500 USD al mes o menos a un «Senior» que además administre la nube.

Pero esta moda lleva solo unos dos años. Y no puede durar mucho. No vamos a regresar a Laravel y CodeIgniter, pero sí vamos a regresar a los servidores intermedios de costo fijo.

Me encuentro en una situación donde el administrador de dinero de la startup me pide alternativas «no nube». Y tengo que lidiar con tres equipos de programadores:

  1. Spring Boot revueltos en tres modos con stacks. Algunos están tratando de migrar a Quarkus o Javelin.

  2. PHP puros con algo de Laravel.

  3. Python. (ese lo levanto en un server aparte y sobrado de 25 USD al mes mientras lo migran a otro lenguaje o un proveedor que els recomendé de 40 USD al mes)

Por eso di la plática del otro día. (Luego pongo la presentación de PowerPoint). El objetivo de este tutorial que haré es demostrar que hay proveedores como Vultr o VPS de terceros donde puedes configurar servers de 4 GB sin problema, pudiendo sacar respaldos y coexistiendo sus tres entornos de trabajo.

Premisas:

  • Sabes dónde contratar un VPS decente.

  • Para resolver problemas Puedes hacer como el barco de los Argonautas: cambiar una pieza y mejora gradual en todo, incluyendo CI/CD.

  • Buscas costos fijos y predecibles para gerencia.

  • Hay servicios intermedios como Vultr, Linode y DigitalOcean, así como Heroku, que te dan la escalabilidad y además te cobran por hora. Usamos Vultr porque es el mejor y porque Linode fue comprado recientemente por Akamai.

Fubar y la Horda o las sorpresas brutales

Este tema es una pequeña reflexión acerca de la relación entre unos eventos que pasaron hace un mes y hace unos ocho años en EVE Online. También tiene cierta relación con eventos de geopolítica del mundo real.

El sábado, conversando en las reuniones en los azulejos, me acordé de un evento que comenté en la mesa sobre el juego EVE Online allá por 2017 y una nave Titán perdida que, por suerte, nos salvó de una masacre solo por aterrizar frente a nuestros enemigos y en perfecta posición de tiro hacia ellos.

Tengo que aclarar que, cuando hablo de la Horda, no me refiero a la Horda de World of Warcraft, sino a la alianza PANDEMIC HORDE de Eve Online. En lo personal, tengo 17 de 70 personajes en la Horda en WOW y 53 en la Alianza, debido a lo confusa que es su ciudad principal, a pesar de que puedo vivir en Dalaran y de lo bien que se ven los orcos de piel roja en armadura.

Yo uso claves gráficas similares al “clima de oficina” y, en este caso, aunque no entro a WoW desde hace uno o dos años, este es un warrior orco rojo comerciante en el reino de la Horda.

En computación, desde hace muchísimos años, en lugar de hablar de x y y, es común usar el término foo y bar, o foo-bar, para explicar conceptos ligados con una consecuencia. Van más o menos así: si foo es comer, bar es pagar la cuenta e ir al baño.

En el juego de simulador espacial EVE Online existen tres zonas de niveles de seguridad: High Sec, Null Sec y Low Sec. Después de mi primer año entendí que, en Null, parecías volverte parte de alianzas que estaban en pleito con todo el mundo. Casi como debe ser en la vida real ser parte de una pandilla, no de un país. Así como las pandillas y las naciones claman su territorio, lo mismo pasa en Null. Te toca ser soldado bajo el control de alguien más, o siervo destruido. Ya tenía la idea de esto desde hace ocho años, pero quise confirmarlo y entré al mismo tiempo a unos seis o siete lugares diferentes de Null, con distintos personajes no relacionados entre sí.

El mejor para mí fue Lateral. Estaba minando hielo con una corporación más o menos decente, en Low Sec (que tiene sus peligros), y recibimos la oferta de ir a Null con una alianza llamada FUBAR, que además tenía una alianza adicional llamada ICON.

La alianza FUBAR, yo siempre pensé que venía de FOO-BAR, pero ahora tiene otro significado en EVE Online. Es un acrónimo de “F*ed Up Beyond All Recognition” o “jodido más allá de lo creíble”. Es una expresión usada en la comunidad de EVE Online para referirse a eventos mayores y catastróficos, como la desaparición de alianzas, coaliciones o pérdidas masivas de flotas.

Voy a tratar de resumir la situación. FUBAR estaba fuerte en apariencia. Yo era, para fines prácticos, el coordinador industrial de varios grupos de ICON y, al momento del evento FUBAR —la desaparición de la alianza FUBAR— tenía 63 POCOS (algo así como estaciones orbitales) y el equivalente de quince naves capitales en construcción, o, en términos de ahora, unos cuatro años de suscripción en materiales en el horno. Y eso representaba solo 1/8 de mis bienes.

Hay algunos puntos a destacar:

  • Quizá ese tiempo fue para mí el más feliz en EVE, por cuestiones de logística. Como premio a lo que estaba haciendo, y haciendo yo un pago simbólico, mi propia corporación de un solo hombre tenía una serie de tres sistemas para mí. Eran las regiones Inmensesea y Fountain.
  • Seguir los procesos planetarios entre unos 30 personajes y coordinar las flotas industriales con defensa incluida y sus naves era similar a hacer deployments de código.

Pero un día…

  • Se hizo una reunión en Teamspeak, que se usaba antes de Discord. Éramos unos cinco de ICON, seis o siete de FUBAR y alguien de una coalición llamada Atlas.
  • Me llamó la atención algo. No sé qué.
  • Y empecé a pensar que, así como en mi trabajo siempre estoy listo para robo de computadora, incendio de servidores, etc., tenía que revisar el plan de contingencia de evacuación de Inmensesea si hacía falta.

Catástrofe.

De repente todo FUBAR desapareció. Y no había dinero de por medio. No es que hubieran robado el capital. Yo tenía bastante idea de las finanzas de ICON. No eran de lo más sanas, pero había razones para pensar que FUBAR tenía el mismo grado de liquidez y, a menos que el líder de la alianza tuviera dinero de su bolsillo, no había nada líquido que llevarse o robar. Solo naves.

Simplemente dejaron de conectarse los Comandantes de Flota, y hubo un descuido en seguir los horarios. En menos de una semana, y realmente de la noche a la mañana, nos enteramos de que llegaba una nueva coalición. Por las rutas de salida que yo tenía, junto con varios de ICON, nos cambiamos a la región Fountain, donde hicimos algo similar. Pero llegó una coalición llamada INIT, que en realidad era una basura. No solo llegaron medio amenazantes, sino que quisieron crear una esclavitud por los recursos de la zona. A mí, por ejemplo, me quisieron expropiar mis 65 POCOS. Lo que hice fue volarlos. Así que levantar nuevos les iba a costar de tres a cuatro horas por cada uno, por lo menos.

Lo interesante es que mi superficie de ataque propia era poca. Al no tener demasiados recursos allí, lo que hice primero en Inmensea y después en Fountain fue irme a producir a otra parte. Por amistades y grupos de jugadores seguí en una corporación en Fountain hasta la pandemia, más o menos, y aproveché para sacar los pocos recursos que me quedaban allí. Lo que me llama la atención es que, de tener más o menos cuatro años de inversión en promedio, al salir de allí ya había vendido o sacado todo , y quedaba como el 3%. Solo tenía un carrier y unas cuantas naves que cabían en él, es decir, unas tres o cuatro naves pequeñas. Y en lugar de 36 personajes en la zona, solo cuatro.

Cabe destacar que, como dije en un principio, sabía que Null era una situación de pandilleros, y que siempre he tenido planes de contingencia. No pongo “todos los huevos en una sola canasta” ni en el mundo real ni en el juego.

Desde que aparecí en el juego han habido tres o cuatro coaliciones grandes: Goons, Pandemic Horde y Test. He tenido personajes con todos ellos. Pandemic Horde me permitía, por su forma de ser, manejar sin tanto lío ciertas naves grandes, como el citado carrier y una nave similar. Test desapareció, para fines prácticos, hace unos años. Goons tienen puntos a favor y en contra. Soy apolítico.

El evento FUBAR más reciente en EVE es la desaparición, para fines prácticos, de Pandemic Horde. En menos de un mes, sus dos corporaciones de jugadores más grandes se han juntado o con los chinos o con la mencionada INIT. Estamos hablando de la desaparición de la segunda coalición o alianza más grande después de Goons DURANTE MAS DE DIEZ AÑOS Y EN MENOS DE UN MES. Literalmente pasaron de 11 mil jugadores a 233, y yo soy dos de esos 233. Evidentemente tengo que ver que hacer con mis naves pero no urge. Ahora, las alianzas grandes son solo Goons, Fraternity, de jugadores chinos, e INIT, que resetearon sus niveles de amistad. Cualquier parecido con Trump es mera coincidencia, pero se pasan el derecho internacional y la decencia por el arco del triunfo.

A mí, de momento, me sorprende. Tengo dos naves que valen uno o dos meses de suscripción en una zona segura con dos personajes de Pandemic Horde. Usarlas en Goons no me conviene y sacarlas de ahí es criminal. Es un poco como tener dinero invertido en un terreno que no quieres ni puedes vender, pero que además no lo necesitas vender.

No sabremos si hubo robo, desidia, traiciones, autodestrucción simple y pura o puñaladas por la espalda en la desaparición de coaliciones o negocios. Por ejemplo, en el asunto del cliente del mundo real, al que llamo “cliente de los monolitos”, pasó el evento FUBAR y me pidieron cometer un delito. Dije que no, y se les cayó la operación. Además, perdieron información de varios años.

El cliente de los monolitos representaba menos de la mitad de mi ingreso.

Yo sigo en High Sec.

El problema del enfoque Universitario en desarrollo

Para fines prácticos soy autodidacta en sistemas. Empecé a programar hace 34 años, en 1991, a los 19 años, leyendo manuales y especificaciones de lenguaje. Sí he tomado algunos cursos: Visual Basic Fundamentals y Visual Basic en New Horizons, allá por 1997. Estudié LSCA en 1995 en una universidad ya desaparecida; no vimos mucho de programación, salvo algo de lenguaje C.

He tomado cursos de bases de datos y he leído y programado mucho. Se dice que dominas un tema a las 10,000 horas. Eso equivale a unos cinco años de semanas de 8 horas diarias. Yo calculo que en mis primeros años trabajé, en promedio, de 80 a 90 horas semanales, llevando el manejo de personal al mismo tiempo y programando en mi casa los fines de semana. Así que puedo decir que en 1993, a los 21 años, probablemente ya tenía las 10,000 horas.

Mientras yo acumulaba horas reales de programación, las universidades seguían atrapadas en ejercicios desconectados de la práctica. Los planes de estudio suelen ser enseñados por personas que jamás pudieron ejercer. Por ejemplo, mi hijo estaba pensando en estudiar sistemas; el plan de UNITEC tenía solo TRES materias de programación: una era Base de Datos y la otra Programación Orientada a Objetos. Además de ser caro e inútil, le recomendé irse por la escuela pública a una Licenciatura (no Ingeniería, porque está negado para las matemáticas) y estudiar por fuera los temas importantes.

Mi trabajo me ha hecho interactuar con dos de las tres universidades públicas más grandes de México. He manejado servidores en la nube para dos de ellas; no creando para terceros, sino siendo el administrador de mis propios servidores y atendiendo a los usuarios. Esa experiencia me confirma que la brecha entre la práctica real y la enseñanza académica sigue siendo enorme. De plano, a veces no tengo idea de por qué los clientes con problemas usan lo que usan. Los programadores se van delos trabajos por lo no manejable, sea tecnología o factor humano. Muchas veces es el stack de tecnologías, y ahí es donde suena el teléfono y me llaman, o recibo un correo electrónico.

Tengo mi propia empresa (medida que tomé por ataques de una secta destructiva para proteger mi patrimonio), pero he pasado por unos quince trabajos de desarrollo. Los últimos quince años han sido con unos tres clientes fijos (incluyendo una de las universidades) y otro que recibía gente de servicio social para tratar de sustentar con «becarios» el costo de no contratar personal. Yo, sinceramente, los usaba para que hicieran videos y cosas así, lo mismo que con sus prácticas profesionales. Les enseñaba a levantar servidores y cómo manejar ciertos problemas con el recurso humano.

La Informática es el manejo de información; la Ingeniería está más enfocada en hardware; y la Licenciatura, en los procesos de negocios. Pero eso sí: casi todos los planes de estudio, a pesar de las calificaciones de 9.x, les dan la teoría pero no la práctica. También les enseñaba a los que querían cómo pasar exámenes en entrevistas de trabajo, así como los exámenes psicológicos. El mejor programador que vi de esos treinta muchachos tronó el psicológico inicial que le apliqué. Ni siquiera lo hubiera pasado a entrevista en el mundo real. Su trabajo fue regular: no entregó el esquema de base de datos, fue grosero con su compañera de clases y no supo decirme qué servicio de Java usaba, pero eso sí, estaba en Azure. ¿Autodidacta? Probablemente.

En mi experiencia, la universidad no prepara ni en lo técnico ni en lo humano. Me encuentro entonces con dos problemas principales:

  1. Desarrolladores que aprenden algo impulsado por la moda y no saben que hay versiones o que el software cambia.

  2. Personas que usan lo que usan solo porque es lo que hay donde están.

La universidad no enseña a evaluar el costo de mantenimiento. Los desarrolladores jóvenes eligen React porque es tendencia, pero si el core de la aplicación maneja datos complejos, muchas veces el costo de Azure o la memoria requerida salen más allá de los límites de estabilidad de una empresa mediana. Ahí entran desde aseguradoras con su propia empresa de software (el lugar más infame en ambiente y contradicciones que me tocó ver en 33 años de trabajo). También he visto casos donde prefieren pagar horas extra a alguien de planta que se la pasa usando Duolingo en yidish, esperanto y alemán en horas de trabajo, que pagar en tiempo y forma a la persona que saca el trabajo (que en este caso era yo, por honorarios).

Pero el costo de mantenimiento es también el costo de la continuidad de negocio. La deuda técnica. Si $2+2=4$ y $1+1+1+1=4$, pero el segundo método es más lento y propenso a errores, eso es lo que hace la mayor parte de las empresas. El enfoque universitario te impone ese $1+1+1+1$, pero el sentido común te dice otra cosa. No es normal que una cajera que gana casi el salario mínimo gaste el 20% de su sueldo en Uber por los días que estuvo a punto de llegar tarde. El tema es la relación con la continuidad de negocio, el «negocio en marcha» como decimos en contabilidad, y ese costo de mantenimiento.

En los últimos tres años nos hemos metido en una situación inmanejable. Ahora vamos por un $((1+1)+2)/2 \times 2$ para programar. Nuestras opciones de ecosistema de stack están mal. No solo por lo que enseñan. Así como las licencias de SQL Server son carísimas (sobre todo para México), tenemos capas en React y Java Spring Hibernate que son inmanejables y consumen mucha memoria costosa. El equivalente a los costos de SQL es querer Azure y AWS cuando tu lista de clientes no llega a 50 grandes y menos de 200 chicos.

Uno de los problemas que encontré entre 2014 y 2015 fue mi primer desastre ajeno a resolver de React. El cliente tenía una corrupción de Maven (el gestor de dependencias de Java, equivalente al Composer de PHP). Tenía un caché corrupto en la PC de alguien despedido. Normalmente habría descargado de nuevo Maven y santo remedio, pero no podía hacerlo por restricciones de permisos. En ese entonces React tendría unos tres o cuatro años y ya presentaba casi todos los problemas actuales. Mis opciones eran: a) llorar, b) formatear o c) hacer otra cosa.

Hice otra cosa. Aunque las incompatibilidades de Java son una razón para no usarlo en mis proyectos propios, eso no significa que no lo sepa. Terminé usando Gradle (que en 2025 sigue vigente) para limpiar el desastre. Explico, de años antrás en Java yo conocía Gradle y sabía que era similar a Maven. En lenguaje simple, el problema parecía ser Maven, y lo que acabé haciendo fue usar otro ‘configurador’ llamado Gradle (para simplificar, diré que es una alternativa a Maven pero más robusta).

¿Cómo identificas qué usa el usuario? Yo uso una bitácora MySQL que, con dos líneas de código en PHP o unas siete en Java, guarda en la base de datos si entraron a /app, /users, /ventas, etc. Tras cuatro días analizando el código infumable de React, mi base de datos me mostró 40 «puntos de entrada». Eso me dio una idea del problema.

Puse Gradle y empecé a migrar. Estaban implementando Spring Boot. Al universitario de hoy, doce años después, le enseñan Maven si bien le va; o si es autodidacta, aprende a buscar librerías (que pueden causar problemas de compliance). La mayoría no busca alternativas. Yo conozco varios modos de hacer las cosas. En un cliente de gobierno tuve que probar siete métodos antes de que uno funcionara por los puertos cerrados y la red inestable. Considerar alternativas no te lo dan en la universidad.

El problema en aquel proyecto era que la dependencia A llamaba a la librería XYZ v1.3 y la dependencia B usaba la v2.0. No podían coexistir. Usé un proceso llamado shadow para decidir qué dependencia usar. Pero el proceso que tampoco te enseñan en la escuela es SIMPLIFICAR, como diría Thoreau en Walden.

Simplificar es lo que salva los proyectos. Meter una dependencia innecesaria es, como diría Bulwer-Lytton en Zanoni: «El que echa agua en un lodazal no hace más que ensuciar el agua». Si tienes un buen elemento, págale. Si necesitas un proveedor, págale. Si quieres seguridad, saca tres respaldos diarios. Es simple.

Finalmente, en aquella ocasión, convertí el proyecto a Gradle en semana y media, quité React y usé Bootstrap con Thymeleaf (que venía por defecto en Spring Boot). Fue hace diez años y ya era un problema. React mete complejidad innecesaria con sus useEffects y la dependencia de componentes de terceros. Si eres responsable, no puedes hacer eso; por compliance, la responsabilidad es tuya si algo falla, especialmente en sectores de salud o financiero.

Un programador arriba del promedio sabe qué es Thymeleaf, aunque sea tecnología de hace diez años. ¿Por qué el 90% de las ofertas de empleo son sobre React y Spring Boot? El problema es que para muchos la curva de aprendizaje se quedó en lo primero que aprendieron. Si quiero un proyecto propio en Java, uso Quarkus. Si quiero que sea mantenible para otros, uso JDBC o Hibernate con Thymeleaf. Y les digo: NO usen Express del stack MEAN como si fuera la espada láser de los Jedi.

Desde 2014 enfrento servidores sobredimensionados en REACT y personas que no saben hacer un «Hola Mundo» sin llamar a quince dependencias. Se trata de buscar alternativas y simplificar. Como parte de lo que haré para mi cliente, levantaré desde cero un servidor Debian 13 con Spring Boot, Gitea y Thymeleaf (además de React para su migración). Su costo anual entre empleados y AWS es de 90,000 USD; ya no pueden pagarlo. Esta solución simplificada cuesta 35,000 USD anuales, solo por salirse de AWS y dejar React a mediano plazo.

Todo porque no buscan alternativas. Como ejemplo, dejaré una adaptación de un programa de terceros de un «carrito de ventas» en Spring Boot / Thymeleaf. El siguiente tutorial tratará sobre Debian y cómo:

  • Instalar LAMP con PHP 8.4.

  • Instalar MariaDB.

  • Instalar Node.js y React.

  • Instalar Gitea y cerrar puertos.

  • Dejar andando Spring Boot bajo Thymeleaf y modo React.

La universidad y autdidactas estándard enseñan a acumular dependencias, pero la práctica exige simplificar para sobrevivir.

Lo más raro es que no solo cobraré por ello, sino que un programa que haga de cero lo que ellos hacen, lo terminaría yo en menos de un mes con Thymeleaf, o en 15 días con PHP puro.

Que es ser Fullstack en 2026

Otros títulos:

  • El espejismo de NPM contra la arquitectura
  • Backend sabe programar y levantar servidores
  • Full stack que no levanta su entorno es frontend junior
Introducción

Durante años,desde 2015 a 2020 el paradigma fue el stack MEAN. Hoy, en 2026, casi nadie menciona Express en las ofertas de empleo (la letra E); el discurso se ha simplificado a “Node.js + React”. Con eso, miles de programadores se autodenominan Full Stack. Pero la realidad es otra: el 80% de quienes ostentan ese título son frontends con pretensiones. Son capaces de correr un npm build y consumir APIs, pero son totalmente incapaces de debuggear un proceso en el servidor o levantar una infraestructura desde cero. Quizá saben un poco de Express. O consideran LEMP mejor que solo es un LAMP con Nginx en lugar de Apache.

Un fullstack que no puede levantar su propio servidor es solo un frontend con pretensiones.

Voy a volver a este tema después:

En mi punto de vista un devops actual debe poder levantar de cero:

  • Infraestructura: LAMP / LEMP

  • Front end: REACT o PHP

  • Back end: Quarkus, Spring Boot, o PHP (con o sin frameworks)

El mito del Full Stack npm

Hagamos una distinción quirúrgica. En 2025-2026, la industria ha confundido la herramienta con la capacidad:

  • npm build ≠ Full Stack: Compilar un frontend es empaquetar, no diseñar arquitectura.
  • Consumir APIs ≠ Backend: Llamar endpoints ajenos es ser cliente, no creador de lógica de negocio.
  • Express básico ≠ Arquitectura: Montar un app.get() siguiendo un tutorial no es diseñar un sistema robusto.
  • Librerías Ajenas ≠ Compliance: Si usas entornos de gobierno, air gapped, de salud, o de dinero no puedes depender de módulos, librerías o dependencias de otros y mucho menos que se actualicen cada vez que les da la gana porque tienes que re certificarte. En estos sectores, cada cambio exige una re-certificación que implica tiempo y dinero. Si tu stack se actualiza solo y rompe la normativa, la responsabilidad (pero rara vez la autoridad) cae sobre ti.

La mayoría depende de conexión constante a internet, tutoriales y librerías externas que no comprenden. Son Full Stacks de teléfono descompuesto: repiten lo que otro hizo, con rendimiento y seguridad degradados en cada copia.

Que si hay un manual en línea para ver desde el celular la orden linux que necesitas si, pero npm o acceso a internet no lo tienes o esta prohibido. Composer y NPM con latencia en sierra de Puebla o en una dependencia de gobierno configurado el dns y firewall con las patas ? Se vale soñar.

Tienes que considerar estas posibilidades del mundo real Mexico 2025:

  • Latencia extrema: Donde un npm install se queda colgado al 10% durante tres horas.
  • Firewalls incompetentes: Donde las reglas de red son tan arbitrarias que nada sale ni entra de forma predecible.
  • Aislamiento: Donde tu única herramienta es lo que ya está instalado en el servidor y lo que traes en la cabeza.
  • No tienes Npm reciente instalado…. No tienes root ….Google es un dominio que no existe segun  el firewall….

Lo que he aprendido es que el «fullstack npm» (react  mas tantito express) no sobrevive fuera de condiciones ideales.

En proyectos serios de 2026, React no vive solo. Es lo que se ve, pero el motor debe ser sólido, corporativo e independiente. El mercado se ha polarizado:

  • Spring Boot (Java): El estándar absoluto, con sus tres modos (Spring JDBC, JPA, Spring Data JDBC y si quieres puedes considerar WebFlux como un cuarto).
  • Quarkus (Java): La evolución ligera y eficiente, ya presente en solicitudes reales.
  • PHP: Contra todo pronóstico, sigue vigente en México: reproducible y soberano en entornos medianos, por COSTO.
  • .NET (C#): Ecosistema aparte, fuerte en corporativos Microsoft.

Mientras tanto, lenguajes como Go o Python brillan en nichos, y otros como Angular o Jakarta EE han perdido tracción. Kotlin, Jakarta EE y Angular (ya de salida) han perdido fuerza en el mercado mexicano. Javelin es de nicho.  El verdadero Full Stack entiende que no se trata de usar la moda, sino la herramienta que garantice que el sistema sea mantenible y lo mas simple posible.

En mi punto de vista un devops actual debe poder levantar de cero:

  • Infraestructura: LAMP / LEMP

  • Front end: REACT o PHP

  • Back end: Quarkus, Spring Boot, o PHP (con o sin frameworks)

Todo lo demás es de nicho. Y si quieren que configures por 1500 USD  Azure o AWS, hay un problema de fondo porque:

  1. Alguien no sabe instalar de cero
  2. Estan casados con aws azure o google cloud
  3. estan sobredimensionados
  4. Esperan crecer y en México a menos que seas empresa muy grande matas moscas a cañonazos
  5. Esperan que lo hagas gratis y le reduzcas costos y se hagan respaldos solos (opuestos en AWS, los respaldos externos cuestan por egress)
  6. Todas las anteriores.
El mito de Responsabilidad sin autoridad
Esto lo comento a cada rato.

No puedes ser experto en ocho razas de perro ni arreglar ocho tipos de coches a la vez. Cuando una empresa pide a alguien que maneje .NET, Python, React Native, Spring Boot, AWS y Azure por un sueldo mediocre, lo que demuestra es que no sabe lo que necesita. Están perdidos en el espacio.

Cuando piden un perfil que domine ocho tecnologías distintas, lo que buscan no es un arquitecto, es un chivo expiatorio barato, o no quieren pagar o estan perdidos en el espacio. Casi nunca quieren que les soluciones el problema. Quieren palabras bonitas como usar un Nissan 2007 para Uber black.

Aquí surge el gran cáncer corporativo de sistemas: darte la responsabilidad pero no la autoridad. Si tú eres el responsable de que el servidor no se caiga, debes tener la autoridad para decidir el stack. Si otro “mete mano” en AWS y el sistema falla, el Full Stack es quien paga por errores ajenos. El arquitecto real exige control sobre su búnker.

Independencia en entornos Air‑Gapped

Cualquiera es Full Stack cuando Stack Overflow está a un clic y las LLM igual. El experto de 2026 se demuestra cuando se cae el internet o cuando el entorno es Air‑Gapped (sin conexión externa). O cuando no tienes acceso a Root.

Si tu despliegue depende de descargar 2GB de dependencias de un servidor en California para funcionar, no tienes soberanía. El verdadero Full Stack tiene el conocimiento en la cabeza y el código en su propio servidor (Gitea), no en la nube de alguien más.

La independencia tecnológica se demuestra cuando se cae el internet y si te piden que te cases con azure o aws.

Definición razonable de Full Stack en 2026

Un Full Stack real es un arquitecto de soluciones que:

  • Configura servidores como DevOps: domina Apache, Nginx, PM2, Gitea y el hardening de bases de datos.
  • Une mundos: levanta un frontend en React que conviva con un backend sólido (Quarkus, Spring Boot o PHP).
  • Domina el debugging: entiende los logs del sistema, no solo los errores rojos del navegador.
  • Garantiza la independencia: sabe que lo simple tiene valor de supervivencia.
  • PROGRAMA !!!!
  • Es proactivo. No falta el que se tarda una semana en poner un certificado SSL y se llama administrador de Red
Mi punto de vista:

El término Full Stack está desgastado. Si no puedes levantar tu propio servidor desde una terminal limpia, no eres Full Stack; eres un frontend con acceso a una API. Por eso digo que soy Devops.

En 2026, el éxito no es saber usar todas las herramientas del mercado, sino saber cuáles sobran para que el sistema sea robusto, privado y eterno.

El verdadero Full Stack en 2026 no es quien sabe todas las tecnologías, sino quien sabe decir no a pedidos contradictorios (react native para web es mezclar mostaza con mermelada) y hace algo simple, que funciona, y es sólido.

Parte 3 Stack Lemp Roundup Gitea y Quarkus

El día de hoy terminaré de instalar este servidor Nginx (LEMP) al tiempo que actualizo en otro ya existente, los dos 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.

Asi que empecemos:

Los 3 puntos clave de hoy para Gitea:

  1. Proxy Inverso (Nginx): Despedirnos del puerto 3000 para entrar por git.tu-dominio.com.
  2. SSL Final: Extender el certificado de Certbot para que el subdominio de Gitea y la ruta /app de React sean inexpugnables.
  3. 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.

Quarkus es Robusto, independiente y eficiente. Como todo buen devops. =)

Ojo con dos errores comunes por ser wordpress:

  • 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.

 

El Backend : Quarkus

Trataré  de explicar y demostrar por qué prefiero la solidez de Java en quarkus sobre Jakarta , Javelin  y sobre todo sobre el «caos» de Node.js con Express. Lo que sigue es:

  1. Instalar el SDK: GraalVM o OpenJDK 21/25 (para ser modernos y eficientes). Se tarda en compilar
  2. Compilación Nativa: Mostrar cómo Quarkus puede arrancar en milisegundos y consumir una miseria de RAM comparado con Spring Boot tradicional.
  3. NO hago la Conexión a la Base de Datos: Ligar Quarkus con la MariaDB que ya instalamos en la Parte 1.
  4. Al final hay un «anexo» Sobre quarkus en desarrollo. Aquí lo verás en modo DEV. Si lees el anexo que esta al final entiendes porqué. Anexo «Uso de Quarkus en producción usando GraalVM».

El hardening o costuras:

Una vez que Quarkus esté arriba, el reto técnico  es:

  1. Proxy Inverso para la API: Hacer que tu-dominio.com/api apunte a Quarkus, mientras /app sigue apuntando a React.
  2. CORS y Seguridad: Configurar el búnker para que solo tu React pueda hablar con tu Quarkus.
  3. Automatización (CI/CD Local)
    • Como ya tienes Gitea, el siguiente paso de «maestro» es configurar Gitea Actions. No lo explico aquí.
    • Hacer que cuando subas código a tu Gitea, el servidor compile Quarkus y React automáticamente y los ponga en producción sin que tú muevas un dedo.
    • Eso es ser Full Stack/DevOps en 2026.

Importante Paso previo a GITEA Quarkus.

Vamos a crear un subdominio, git.tu-dominio.com , la mayoría usa www.tu-dominio.com ,pero como hay cientos de empresas que venden dominios, a ti te corresponde encontrar como hacer un registro A , que apunte a la dirección IP. Como diría Dorothy de el Mago de Oz, creo que ya no estamnos en cpanel Toto.

No prosigas hasta que hayas hecho ese paso y hayan pasado unos diez minutos.

Ya que estés listo, hay que crear un archivo nuevo.

nano /etc/nginx/sites-available/git.tu-dominio.com

Y ahi pones esto:

server {
listen 80;
server_name git.tu-dominio.com;

# Log de errores para debuggear si algo falla
access_log /var/log/nginx/gitea_access.log;
error_log /var/log/nginx/gitea_error.log;

location / {
proxy_pass http://localhost:3000;
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;

# Ajuste para subidas de archivos grandes (ej. commits pesados)
client_max_body_size 512M;
}
}

TIP IMPORTANTE

Notarás que puse client_max_body_size. Puedes ajustarlo, pero es vital. Si no lo pones, cuando quieran subir un repositorio de más de 1MB por HTTP, Nginx les va a escupir un error 413 Request Entity Too Large. Un Devops de 2026 no deja que un límite por defecto arruine su Gitea. En lo personal creo que 256 es mas que suficiente pero  el 512 no sobra.

Que hacemos para enlazar git.tudominio a gitea?

  • Enlazar el archivo: ln -s /etc/nginx/sites-available/git.tu-dominio.com /etc/nginx/sites-enabled/
  • Validar y Reiniciar: nginx -t && systemctl reload nginx
  • Certbot (El momento de la verdad): certbot –nginx -d git.tu-dominio.com (Aquí Certbot leerá tu archivo de Nginx y le inyectará automáticamente las líneas de SSL).
  • Por precaución y por el manejo de puertos lo mejor es probar nuevamente el dry run de cert bot.
    • certbot certonly –dry-run -d git.tu-dominio.com
    • Lo mas seguro es que te de tres o mas opciones. Selecciona la que dice Nginx
      • las versiones más recientes de Certbot aplican el Redirect automáticamente. Antes te preguntaba si querías redirgir automáticamente (Option 2 por defecto) o que, al detectar que ya tienes otros sitios con Redirect, asuma que quieres lo mismo para mantener la coherencia del búnker.

Prueba ahora con http://git.tu-dominio.com y debe abrir normal y con candado verde. VERIFICA que el certificado sea valido.

Que tenemos que hacer ?

Bueno….

en este momento vives en una ip. Lo que significaque si te mueves de zona por ejemplo de Mexico a Estambul,   i de useast a amsterdam en AWS, va sa tener problemas. Vamosa ligar Gitea al nombre del dominio. Además clonar, respaldar o manejar repositorios en direcciones IP y no dominios, es mala práctica además de incómodo.

Vamos a decirle quién es oficialmente.

  • Abre el archivo de configuración: nano /etc/gitea/app.ini
  • Busca la sección [server] y edita estas líneas: (Asegúrate de que tengan el dominio y el HTTPS)
  • [server]
    DOMAIN = git.tu-dominio.com
    HTTP_PORT = 3000
    ROOT_URL = https://git.tu-dominio.com/
    DISABLE_SSH = false
    SSH_DOMAIN = git.tu-dominio.com
    SSH_PORT = 22
    Guarda (Ctrl+O, Enter) y Sal (Ctrl+X).
  • Reinicia Gitea para que lea su nueva identidad: systemctl restart gitea
  • Y como recordarás tenemos el puerto 3000 abierto. Ahora hay cerrarlo, o «colgar el teléfono» porque yaestamosusando el puerto 443 por el SSL
    • ufw delete allow 3000/tcp # Cierra el puerto en el firewall
    • ufw status # Verifica el estado: 

ahora Solo se entra por el subdominio seguro. https://git.tu-dominio.com

¿Ya reiniciaste Gitea? Entra a la web y verifica que en la parte inferior o en los enlaces de clonar ya aparezca tu dominio con HTTPS. Si eso está listo, ya quedó Gitea.

Ahora vamos con Quarkus.

Instalación de Quarkus

Para instalar Quarkus de forma profesional en un entorno Debian (sin llenar el servidor de basura), lo ideal es usar SDKMAN!. Es la herramienta estándar para desarrolladores Java/Quarkus porque te permite gestionar versiones sin pelearte con las variables de entorno manualmente.

Aquí tienes los pasos para dejar el motor listo:

1. Instalar SDKMAN!

Primero, necesitamos zip y unzip (si no los tienes) para que SDKMAN pueda trabajar:

  • apt update && apt install zip unzip curl -y
  • curl -s «https://get.sdkman.io» | bash # instalamos el gestor sdkman
  • source «$HOME/.sdkman/bin/sdkman-init.sh» # la comillas son importantes
  • sdk version # te vaa dar un numero y significaque ya estamos del otro lado y esta instalado.
  • sdk help # probar que si corrió la instalación.

2. Instalar el Java adecuado (El corazón)

Para Quarkus en 2026, lo ideal es Java 21. Vamos a instalar la versión de Temurin (de la fundación Eclipse), que es de las más estables y ligeras:

  • sdk install java 21.0.2-tem # se va a tardar mas que otros procesos …..
  • usa en terminal:    java -version # verificar que todo esté en orden va espacio entre java y version
    • Si estas en una maquina antigua no instalacion limpiapuede ser ue necesites
      • sdk use java 21.0.2-tem
      • Salir y volver a entrar a SSH. Recuerda usar java – version
  • Si obtienes «OpenJDK Runtime Environment», Java ya esta instalado

3. Instalar Quarkus CLI

Ahora sí, instalamos la herramienta de línea de comandos de Quarkus que nos permitirá seguir el proceso. Ejecuta:

  • Ejecuta: sdk install quarkus
  • Verifica con: quarkus –version

Nota Plus. Tengo mis propios medios de verificar servidores, pero prefiero no ponerlos en publico, aisque para fines de este tutorial, haré un monitor de memoria y espacio en uso, usando quarkus y react. Normalmente clonaría uno de mis repositorios privados pero en este caso vamos a hacerlo de cero y simplificado.

3.1 Crear el proyecto «Monitor-Instance»

Es posible que el código este funcionando en un vps, docker, servidor, pero es mas exacto decir que es instancia de Quarkus, y es indiferente o agnóstico a si es Nginx o apache. Así que llamaremos a este proyecto monitor-quarkus-instance y lo pondremos en la carpeta de git que creamos antes.

RECORDATORIO HICIMOS ESTO:

mkdir -p /home/git/proyectos

cd /home/git/proyectos

Vamos a crear el esqueleto pero tenemos que considerar JSON que es lo que consume REACT. Eso lo hacemos con el –extension=resteasy-jackson que ves abajo.

1. Crear el proyecto con el nombre correcto Ubícate en la carpeta que definiste para tus proyectos de Git y genera la app:

  • cd /home/git/proyectos
  • quarkus create app monitor-quarkus-instance –extension=resteasy-jackson
  • cd monitor-quarkus-instance
    • Notaras que te dice sucessfile generated

2. Crear el Recurso (El código del monitor)

Vamos a crear el archivo que lee el «hardware» del servidor. A ti como Admin te interesa ver memoria y uso de disco. Quarkus por defecto crea un GreetingResource.java, vamos a sustituirlo por nuestro monitor:

 

Ojo con esto. CUalquier script kiddie va a estar buscando «stats». Yo usaria un lugar no muy comun, como mis iniciales que son aoa, asi que uso en este ejemplo statsaoa o puede ser statsTUNUMERODEMPLEADO. La lógica es que un bot de escaneo va a buscar /stats, /admin, o /health, pero si lo renombras a algo que solo tú sabes, como statsaoa o un token tipo stats2026aoa, acabas de quitarle el 99% del ruido de los logs de ataques automáticos.

Tienesque tener cuidado que no desaparezcan las comillas. es un error comun.

  • nano src/main/java/org/acme/MonitorResource.java

Pega este código (optimizado para ser ligero):

package org.acme;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;

@Path(«/statsaoa»)
public class MonitorResource {

@GET
@Produces(MediaType.APPLICATION_JSON)
public Map<String, String> getStats() {
Map<String, String> stats = new HashMap<>();

// Fecha y hora actual (Instancia)
stats.put(«hora», LocalDateTime.now().format(DateTimeFormatter.ofPattern(«yyyy-MM-dd HH:mm:ss»)));

// Uso de memoria RAM (comando free)
stats.put(«memoria», executeCommand(«free -m | awk ‘NR==2{printf \»%.2f%%\», $3*100/$2 }'»));

// Espacio ocupado en disco (comando df)
stats.put(«disco», executeCommand(«df -h / | awk ‘NR==2{print $5}'»));

return stats;
}

private String executeCommand(String command) {
try {
// El comando debe ir entre comillas
Process process = Runtime.getRuntime().exec(new String[]{«/bin/sh», «-c», command});
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
return reader.readLine();
} catch (Exception e) {
return «Error: » + e.getMessage();
}
}
}

3. Configurar la seguridad (CORS) y el mayordomo del Búnker

Antes de lanzar el motor, necesitamos que Quarkus sepa que tiene permiso para hablar con nuestro Front-end. En el mundo de 2026, los navegadores bloquean cualquier petición que no esté explícitamente autorizada.

Edita el archivo de propiedades:

* nano src/main/resources/application.properties

Añade estas líneas (esto es el equivalente a darle una «lista de invitados» a tu portero o mayordomo):

Properties Pega tal cual

# Permitir que React consuma la API desde tu dominio
quarkus.http.cors=true
quarkus.http.cors.origins=https://tu-dominio.com

4 Hora de probarlo.

Es hora de probar si nuestro código realmente lee el hardware. Ejecuta el modo de desarrollo:

  •  cd /home/git/proyectos/monitor-quarkus-instance
  • chmod +x mvnw # da permisos de ejecución
    • ls -l mvnw  # debes ver color verde una x de  ejecutable en permisos
  • ./mvnw quarkus:dev

(Si es la primera vez, verás que descarga las dependencias. Es el proceso de armar la maquinaria). Una vez que veas que el sistema está listo, abre otra terminal y lanza un ataque de prueba (un simple curl):

Con la letra q te regresa saliendo del shell, al modo terminal. Y debes ver un BUILD SUCCESS en eltras verdes.

Pero no  vas poder probarlo por un detalle simple. Solo esta vivo mientras el modo dev esta presente. Asi que lo normal sería lanzar una segunda terminal de root, pero aveces, por ejemplo vultr no te deja. Asi que lo mejor es que uses powershell o un terminal y hagas desde allí

  • ssh root@tu-ip-de-vultr
    • ahi si puedes abrir las ventanas que quieras. pone el password y ejecuta esto
  • curl http://localhost:8080/statsaoa

Si te responde un JSON con la memoria, el disco y la hora, felicidades: has creado un backend independiente que no le debe nada a nadie.

Y esto es lo que vas a recibir, mas o menos…

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
root@xxxxxx:~# curl http://localhost:8080/statsaoa
{«memoria»:»43.26%»,»hora»:»2026-01-02 20:27:56″,»disco»:»17%»}root@xxxxxx:~#

Ahora si lo que falta es cerrar la puerta. Cuando entras a tu casa, luego cierras la puerta no ?

Hacer seguro el cierre de puertas:

Como ahora ya sabemos que Quarkus responde en el 8080, vamos a cerrar ese puerto al mundo y dejar que solo Nginx hable con él.

Edita tu archivo de Nginx: nano /etc/nginx/sites-available/tu-dominio.com

Añade esto dentro del bloque server: OJO : La barra después del 8080 es super importante hazme caso y dame las gracias después.

Nginx

location /api/ {
proxy_pass http://localhost: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;
} # <— No olvides cerrar la llave

Y despues:

  • systemctl reload nginx # recargamos nginx

Y el final es ?

Un programador de FRONT END haría esto en un widget

import React, { useState, useEffect } from ‘react’;

const MonitorAOA = () => {
const [stats, setStats] = useState(null);

useEffect(() => {
const fetchStats = async () => {
try {
const response = await fetch(‘https://tu-dominio.com/api/statsaoa’);
const data = await response.json();
setStats(data);
} catch (err) {
console.error(«Instancia no responde», err);
}
};
fetchStats();
const timer = setInterval(fetchStats, 30000); // Actualiza cada 30 segundos
return () => clearInterval(timer);
}, []);

if (!stats) return <div>Conectando con la instancia…</div>;

return (
<div style={{ border: ‘1px solid #333′, padding: ’15px’, borderRadius: ‘5px’, backgroundColor: ‘#000’, color: ‘#0f0’ }}>
<h4>SISTEMA DE MONITOREO AOA</h4>
<p>RAM: {stats.memoria}</p>
<p>DISCO: {stats.disco}</p>
<small>Sincronizado: {stats.hora}</small>
</div>
);
};

export default MonitorAOA;

Yo haría algo para que quarkus estuviera siempre activo. Pero tiene sus… peligros y lo que me da de comer. Eso va al final en el anexo.

Para que todo este siempre activo Cómo dejarlo encendido permanentemente (Nivel DevOps)

Para esto usaremos systemd, que es el administrador de procesos de Debian. Es lo mismo que mantiene vivos a Nginx y MariaDB.

1. Crea el archivo de servicio:

Bash

nano /etc/systemd/system/monitor-quarkus.service
2. Pega este contenido (Ajusta tus rutas):

[Unit]
Description=Monitor Quarkus Instance AOA
After=network.target

[Service]
Type=simple
User=root
# Ruta a tu carpeta del proyecto
WorkingDirectory=/home/git/proyectos/monitor-quarkus-instance
# Comando para arrancar en modo producción (usando el script de Maven)
ExecStart=/home/git/proyectos/monitor-quarkus-instance/mvnw quarkus:dev -Dquarkus.http.host=0.0.0.0
Restart=always

[Install]
WantedBy=multi-user.target

3. Activa el «Fantasma»:

systemctl daemon-reload
systemctl enable monitor-quarkus
systemctl start monitor-quarkus

Ahora, aunque cierres PowerShell, te vayas a dormir o reinicies el VPS de Vultr, tu API en https://tu-dominio.com/api/statsaoa seguirá respondiendo.

Verificación final:

systemctl status monitor-quarkus #  Debe estar «active (running)»
curl https://tu-dominio.com/api/statsaoa #  Debe devolver JSON
curl https://git.tu-dominio.com #  Debe abrir Gitea con SSL

 

Y la parte 4:

Tengo ocupaciones del mundo real. Pero me encantaría hacerte entrar al mundo de Gitea Actions o la Compilación Nativa con GraalVM en Quarkus. Si tienes menos recursos, o te harta esperar la compilación de Native Quarkus, javelin está bien para proyectos propios pero no hay mucho mercado, ofertas de trabajo ni desastres que arreglar. Uno no vive solo de la elegancia del código, sino de solucionar problemas donde hay dinero y demanda.

Lo mas seguro es que no lo haga en NGINX una parte 4 con Gitea Actions por lo que explico en el watercooler (abajo de laconclusión), pero que si haga algo muy parecido a este documento, pero para levantar LAMP., con apache, spring boot en debian 13 y React con php. Las razones las verás abajo.

Conclusión:

Al terminar este setup, mi servidor Debian consume apenas unos megas para reportar su estado. No necesité un tablero de control de AWS de 100 dólares, ni una infraestructura pesada que se come la RAM antes de servir la primera petición. Como mi Motorola G31: hace exactamente lo que necesito, es eficiente y el control biométrico (mi endpointstatsaoa) es mío. En 2026, lo simple tiene valor de supervivencia

Si. Estoy consciente que esto es todo menos simple por sí mismo. Ver todo lo que carga la primera vez que cargas quarkus dev es impresionante.  Hay formas mas directas, pero esto es lo mas directo usando Java React. Personalmente creo que algo está mal si la solución eficiente , como esta, usa 2 gb de  ram para tener activo el ecosistema. Y por eso cuando se trata de proyectos propios, me voy por alternativas que no son java. Pero Quarkus es lo mas simple de java. Quarkus es lo mejor de un mal necesario (Java enterprise)

Plática de Watercooler:

En el entorno corporativo a veces las personas con experiencia están dispuestos a darte consejos por años de experiencia, y en USA se dice platica de watercooler a una mezcla entre eso y chismes.. En mi propia oficina suelen venir por café y galletas. En lo personal creo que tenemos complejidad innecesaria. Hay demasiados puntos de falla. Si esto es la versión simplificada imaginate como  estará lo demás.

He tenido casos que despues de explicar esto crean muchos micro services. Y luego me llaman a arreglar desastres.

Dije que podiamos usar giteaa actions . Aqui no lo vi a propósito. Lo uso porque se lo que estoy haciendo. Pero cuando tienes cinco o seis programadores con su propia idea de arquitectura y apis, vas aacabar con decenas de procesos fantasma que consumen la memoria. Tener un /statsaoa es una cosa pero  treinta o demas microservices, aunque diga amazon que es bueno, es incontrolable y te lleva a mas puntos de falla,  mayor costo y a diversos vectores de ataque. Creo que el punto que pone mas complejidad es REACT actualmente.

Un punto: La instalación de ORACLE se suele cobrar aparte. Usando un ejemplo, yo instalo servidores si me pagan por ello o si no hay mas remedio. Es responsabilidad y la autoridad es que me paguen.

Sin embargo, por simplicidad lo primero que hago es ver la queja. Los costos de Egress de Amazon. O de WAFs . Lo primero es irte por un costo estable. Regresate a vultr o un proveedor decente de vps. Reduce ese costo.

Y luego arregla el desastre de decenas de microservices que alguien hizo. Es mi principal fuente de ingresos. Por eso finalmente suelo terminar con algo de vultr o un proveedor de vps que no menciono , con apache, y sacando respaldos por una iguala para defender a la empresa de sus mismos programadores.

Un server es tan bueno como su admin. Te vas a enfrentar a muchos programadores bien intencionados pero mediocres. Y muchos admin que no ven el problema con la complejidad innecesaria de su infraestructura.

ANEXO: Uso de Quarkus en producción usando GraalVM

Para fines didácticos, en este post usamos el modo quarkus:dev. Sin embargo, un verdadero DevOps de 2026 sabe que en producción el motor debe ir «sellado» para maximizar la eficiencia y el ahorro de RAM que tanto hemos defendido.
Este anexo lo suelo pasar impreso en word, asi que lleva un formato diferente.

1. Preparando el motor para el mundo real

Antes de configurar el servicio final, debemos compilar nuestra aplicación para generar el paquete de distribución:

bash
# Ubícate en la carpeta del proyecto
cd /home/git/proyectos/monitor-quarkus-instance

# Compilar para producción (Modo JVM estándar)
./mvnw package

Esto generará una carpeta en target/quarkus-app/ con todo lo necesario.

Verificación:

bash
ls -lh target/quarkus-app/quarkus-run.jar
# Debe mostrar el JAR compilado

2. Ajuste del «Fantasma» (Servicio systemd)

Debemos modificar el archivo /etc/systemd/system/monitor-quarkus.service para que apunte al binario compilado y no al gestor de desarrollo. Aquí tienes las dos rutas posibles:

Opción A: Modo JVM (Estable y rápido)

Nota:

TIP DE RUTA: Como usamos SDKMAN, para saber qué poner en ExecStart, ejecuta en tu terminal: whereis java o readlink -f $(which java) La ruta suele verse así: /root/.sdkman/candidates/java/current/bin/java

Si usas el Java 21 que instalamos con SDKMAN:

ini
[Unit]
Description=Monitor Quarkus Instance AOA (Producción JVM)
After=network.target

[Service]
Type=simple
User=root
WorkingDirectory=/home/git/proyectos/monitor-quarkus-instance
# ↓ La clave del cambio está aquí
ExecStart=/usr/bin/java -jar /home/git/proyectos/monitor-quarkus-instance/target/quarkus-app/quarkus-run.jar
Restart=always

[Install]
WantedBy=multi-user.target

Consumo estimado:

  • RAM: ~70-100 MB
  • Inicio: ~2-3 segundos

Opción B: Modo Nativo (El Santo Grial de la eficiencia)

Si decides compilar usando GraalVM para que el servidor arranque en milisegundos y consuma apenas una fracción de RAM (compilación nativa):

Primero, compilar nativo:

bash
#Solo si usas la Opción B (Nativo)
chmod +x target/monitor-quarkus-instance-1.0.0-SNAPSHOT-runner
# Esto tarda 5-10 minutos (es normal)
./mvnw package -Dnative

# Verificar que se creó el binario
ls -lh target/*-runner

Luego, ajustar el servicio:

ini
[Unit]
Description=Monitor Quarkus Instance AOA (Producción Nativa)
After=network.target

[Service]
Type=simple
User=root
WorkingDirectory=/home/git/proyectos/monitor-quarkus-instance
# ↓ Apunta al ejecutable nativo
ExecStart=/home/git/proyectos/monitor-quarkus-instance/target/monitor-quarkus-instance-1.0.0-SNAPSHOT-runner
Restart=always

[Install]
WantedBy=multi-user.target

Consumo estimado:

  • RAM: ~30-50 MB (¡3x menos que JVM!)
  • Inicio: ~0.05 segundos (50 milisegundos)

¿Por qué hacer este cambio?

Seguridad:
El modo dev deja herramientas de depuración abiertas que no quieres en la calle. Es como dejar la puerta de tu casa abierta «por si acaso».

Rendimiento:
El paquete quarkus-run.jar está optimizado por el «re-augment» de Quarkus para cargar solo lo necesario. No arrastra todo el peso del desarrollo.

Independencia:
Al usar el ejecutable nativo (Opción B), tu servidor se vuelve una pieza de relojería suiza que no depende ni siquiera de una JVM externa para correr. Es un binario único, como Gitea.

3. Aplicar los Cambios

# 1. Edita el servicio con tu opción elegida
nano /etc/systemd/system/monitor-quarkus.service

# 2. Recarga la configuración de systemd
systemctl daemon-reload

# 3. Reinicia el servicio con el nuevo "piloto"
systemctl restart monitor-quarkus

# 4. Verifica que todo está bien
systemctl status monitor-quarkus

# 5. Prueba el endpoint
curl https://tu-dominio.com/api/statsaoa

Tabla Comparativa (Para Tomar Decisión)

Modo RAM Inicio Build Time Complejidad Recomendado Para
dev ~150 MB Inmediato 0 min Baja Aprendizaje
JVM ~80 MB 2-3 seg 1-2 min Baja Producción normal
Nativo ~40 MB 0.05 seg 5-10 min Media Máxima eficiencia

Nota Final del Autor

Si haces este cambio, recuerda ejecutar systemctl daemon-reload y systemctl restart monitor-quarkus para que el sistema reconozca al nuevo «piloto» de producción.

Mi recomendación: Para empresa mediana (50-150 usuarios/día), el Modo JVM (Opción A) es perfecto. Ahorras el tiempo de compilación nativa y el consumo de RAM sigue siendo ridículamente bajo comparado con Spring Boot o Node.js.

Reserva el Modo Nativo (Opción B) para cuando realmente necesites el último gramo de eficiencia o tengas restricciones extremas de RAM. Es el equivalente a pasar de un Motorola G31 a uno ultra-optimizado que solo hace llamadas y SMS pero dura 2 semanas con una carga.

Parte 2 Levantando Stack LEMP Node React Gitea

Este texto lo realicé en unas cinco horas mientras lo levantaba en dos servidores simultáneos, uno de cero y otro ya existente ycon pausas paradescansar, comer y jugar Eve online. Es primero de enero.

La razón de seguir este orden es que la mayoría de los desarrolladores trabajan con React, mientras que Node es independiente y puede integrarse con distintos backends. Por eso, en esta sección me enfocaré únicamente en Node, React y Gitea como prueba reproducible. Quarkus (mi preferido) y TinaCMS los dejaré para más adelante, ya que responden a necesidades específicas del cliente.

Objetivo:

Palabra Clave : React es un mal necesario

React se construye no se instala.

Entorno Debian 13 con Nginx Instalando como root

Nota: es posible que algun guion haya cambiado de forma, en curl. son guiones normales.

⚠️  Alcance de Este Manual

Este es un manual simple y reproducible para levantar un stack funcional. No es una guía exhaustiva de configuración avanzada.

Lo que NO cubre este manual (intencionalmente):

1. Configuración de .env en React

  • Las variables de entorno son específicas de cada proyecto
  • Configurarlas mal puede exponer credenciales sensibles
  • Si ya tienes un servidor existente en producción, experimentar con .env puede romper cosas
  • Aprende esto en un ambiente de desarrollo local primero, no en producción

2. Servidor de correo (SMTP)

  • OVH Cloud: Tiene fama de spammers, tus correos caerán en spam o serán bloqueados
  • Vultr: El puerto 25 (SMTP) está cerrado por defecto, necesitas contactar soporte para que te lo abran
  • Configurar SMTP mal puede convertir tu servidor en zombi de spam (y quedar en blacklists globales)
  • Si necesitas correo, usa servicios externos como SendGrid, Mailgun o AWS SES. Yo recomiendo Twilio.

3. Configuraciones avanzadas de seguridad

  • Hardening exhaustivo de cada servicio
  • Configuración de WAF (Web Application Firewall)
  • Intrusion Detection Systems (IDS)
  • Estas son importantes, pero cada una requiere su propio manual

4 Lo que SÍ cubre:

  • Stack completo: Nginx + Node + React + Gitea + MariaDB
  • Seguridad básica pero sólida (UFW, permisos correctos)
  • Configuraciones que funcionan «out of the box»
  • PM2 para inmortalidad de procesos
  • Control de versiones con Gitea (soberanía sobre tu código)

Si necesitas más, este manual te dio la base para investigar sin romper cosas.


Filosofía de este manual:
Prefiero que tengas un servidor simple pero funcionando, que un servidor «perfecto» que nunca terminas o que rompes intentando configuraciones avanzadas sin entenderlas.

Una vez que esto funcione, tendrás meses para aprender .env, SMTP, hardening avanzado y demás. Pero si empiezas por ahí, nunca tendrás ni siquiera el servidor básico.

Paso 1: Instalación de Node.js 22 LTS y PM2

En Debian 13, queremos la versión más estable y moderna. No usaremos la de los repositorios estándar (que suele ser antigua), sino el repositorio oficial de NodeSource.

  • Configuraremos PM2 para que el servidor sea «autocurativo» (si una app de Node falla, PM2 la levanta en milisegundos).
  • React : Explicaremos cómo hacer el build de una app de React y cómo usar Nginx para servir esos archivos estáticos de forma ultra rápida (sin pasar por Node, que es lo más eficiente).
  1. Agregar el repositorio de Node.js 22

Ejecutamos esto para que el sistema sepa de dónde bajar la versión 22:

  • curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash –
  • apt install -y nodejs
  • Verificamos dos veces:
    • node -v
    • npm -v
      • v22.21.0 y 10.9.4 en mi caso

Prefiero el control directo sobre mis servidores; no me interesa ser esclavo de los Docker y Kubernetes ajenos. En lugar de añadir capas de abstracción que devoran tiempo en hardening y complican la operación, utilizo PM2 como mi gestor de procesos. Me da estabilidad, reinicios automáticos y monitoreo en tiempo real sin el lastre de una infraestructura pesada. Es reproducibilidad sin sobreingeniería: mantenemos el servidor vivo y eficiente, sin los costos ocultos ni las limitaciones de quienes dependen ciegamente de la nube.

Muchos programadores siguen tutoriales básicos o sobredimensionan con Docker cuando no lo necesitan, y otros instalan Node sin PM2. En lo personal, creo que PM2 es el punto medio ideal entre control, rapidez y flexibilidad.

Enlace de documentacion de pm2 https://pm2.keymetrics.io/docs/usage/quick-start/

  1. Agregar PM2

Instalar PM2 npm install pm2 -g

Al ejecutar esta orden, vas a ver un «rombito» de progreso. Si no ves errores en letras rojas, déjalo correr. Todo va bien.

pm2 startup

OJO: Normalmente, esto te da una línea larga que empieza con sudo env PATH… que tienes que copiar y pegar. Pero como Debian es otro nivel de eficiencia, a veces no te la pide porque detecta el sistema de inmediato. Si quieres forzarlo o asegurarte, usa:

pm2 startup systemd

En mi experiencia, como PM2 se integra tan bien con Debian, es probable que te diga que ya creó el root.service automáticamente (algo que he tenido que pelear más en Rocky Linux o Ubuntu).

ejecuta

pm2 save

Para revisar que ya está cargado, ejecuta: systemctl status pm2-root

Si el resultado es active (running), felicidades: ya tienes la infraestructura lista para que cualquier app de Node o React (vía SSR) se cargue solo si se cae o que sea inmortal.

Pero…

Puedes tener problemas con los enlaces de linux. Asi que sugiero que hagas esto para evitar que te diga que la ruta no existe:

# Si tu prefix fue /usr/local:
ln -s /usr/local/bin/pm2 /usr/bin/pm2

# Si tu prefix fue otra cosa, ajusta la ruta.
# Luego prueba:
pm2 -v

y por ultimo, para olvidar las rutas antiguas y cargas las nuevas :

hash -r

porqué ?

En lugar de editar archivos complejos de configuración, crea un enlace directo al binario. Usas Debian porque prefieres la solución base, en lugar de Ubuntu. Es un ejemplo de soluciones quirúrgicas:  ln -s y a seguir trabajando. Menos drama y más control.

Nota importante:

Suponemos que estas usando root: Digo que el servicio se llama pm2-root porque lo instalé como usuario root. Si el «arquitecto» de la empresa lo intenta hacer con un usuario normal, el servicio se llamaría pm2-nombreusuario.

Paso 2: Instalación de REACT

Aqui tengo que contar dos historias, que verás con margen a la derecha, si quieres brincarlas pero explica mi enfoque de la complejidad innecesaria de react

En el año 2002 el director general de una empresa me contrató para hacerle en Visual Basic un sistema de facturación que pudiera imprimir facturas de 60 páginas, con descripciones muy detalladas y el total solo en la última. Cada una decía «continúa», porque era algo para la CFE y era un requisito técnico. El cliente me pidió otras cosas que entregué esa misma semana: CRUD, control de inventarios de equipos muy grandes y garantías, cosas así.

Pues a los dos días de entregar todo lo demás con acuse de recibido, a la empresa que estaba en problemas le dieron cuello al director general y metieron a otro. Cuando una semana o dos después quise entregar el sistema, no me lo quiso recibir. La razón era que no le servía. Lo que necesitaba era otra cosa. Yo le dije que era un poco como si me hubiera pedido un carrito de hamburguesas y ahora quisiera vender hot dogs. Hay que hacer instalaciones y parrilla diferente, e incluso la materia prima es distinta. Uno lo vendes de a tres y el otro en diez o doce variedades. Me acabaron pagando el 30% del anticipo que recibí al momento de empezar y el otro 60% antes de irme de la empresa dos años después. El sistema nunca lo usaron.

El problema de React es que las necesidades cambian. Hace tres años veías en todos lados Laravel, ahora es React. Creo que es una moda pasajera. Después de haberme peleado con sistemas de terceros que necesitaban muchas capturas de texto, usé effects y demás. Sí, React es el estándar, pero no es necesariamente lo mejor.

Pero si te pagan por eso, lo haces.

La segunda historia fue a mediados de 2010. Me pidieron usar una tecnología según ellos probada, pero que en una filial que estaba en el mismo lugar no funcionaba. Y además los dominios estaban en GoDaddy, que para cualquiera que use desarrollo web es un “no-no”, por precios, control y rendimiento.

Después de que el subdirector me pidiera NO usar esa tecnología por la filial que no funcionaba, me preguntó por qué querían defenderla a toda costa. Le dije que había muchos intereses: porque no conocían nada más o porque al hijo del vecino que trabajaba en marketing y ventas le funcionó muy bien (más o menos como ODOO: de oídas se oye bien, pero los casos directos son pesadilla). Así que les dije que era un poco el teorema de la mosca. Era una empresa de comunicaciones vía satélite.

Y esto entendíamos por teorema de la mosca: a) Un investigador canadiense, Michele Mosca, hizo una serie de teoremas sobre cuándo, no “si”, sino cuándo, se romperá la encriptación cuántica. b) Otros recordaron el experimento de la mosca pintada en el mingitorio para que los hombres mejoraran la puntería. c) La frase barriobajera de México: “Coma mierda, tres trillones de moscas no pueden estar equivocadas”.

A lo que voy es que si se trata de usar Node.js o Spring Boot, yo prefiero frontend Vue o Next.js. Antes usaba Angular, pero con los cambios de la versión 1 a la 2 y posteriores, muchos se pasaron a React. React es el estándar ahora.

Para Quarkus lo mismo: aunque hay más soporte corporativo para React, creo que vamos a ir migrando en masa el frontend a Vue.js con el paso del tiempo. Y en lo personal, muchas veces algo con PHP puro es suficiente.

React tiene dos ventajas:

  • Es el estándar y puedes conseguir más personal especializado.
  • Junto con Spring Boot, es el estándar.

Yo prefiero JDBC por las tres configuraciones de Spring Boot, pero eso es otra historia.

Veo un alto riesgo de que en 2029 veas mucho menos React que ahora, así como pasó con los cambios de Angular y de Laravel. Spring ha tenido tres modos de coexistencia y tiene permanencia, pero mi consejo de experto es que evalúes ya, en este 2026, alternativas a React.

Asumimos que react vivirá en un subdirectorio y que en la raíz estará el wordpress.

React vive en el navegador del cliente, no en tu servidor. Lo que instalamos en el servidor es el entorno de construcción (Node.js/npm)

Con node ya instalamos npm.

Pero tenemos dos problemas.

  1. queremos independencia y soberanía
  2. queremos respaldos y control de versiones.

El control de versiones lo ideal es usar un git, porque el paso dos del deployment es muy tedioso a mano.

Antes se usaba el termino de editar en un servidor a pelo. Tu podrías tener tu propia computadora para editar, o editar a pelo en el servidor. Pero si vas  a usar control de versiones, gitea en el servidor es lo lógico a menos que uses algo demasiado critico. Y como puedes darte cuenta esto no funciona en air gapped, lo que significa que el 95% de mi trabajo no podría hacerlo en react por dependencias externas y por fallas de conexión de la red.

Así que vamos a suponer opción b. Lo vas a hacer en el servidor y con Gitea en lugar de github. Si haces otra cosa felicidades. Pero lo que a mi me funciona es esto. Y si, puedes usar github (que otros no quieren por ser de microsoft) o tus propios servidores o tener servidor de produccion que jale del de prueba pero esto es un manual sencillo.

Dije que  vamos a suponer que vas a usar la opcion B. Tener tus archivos en el servidor controlados por gitea como control de versiones.

React no se instala. Se construye:

No queremos mezclar el código fuente con los archivos públicos de Nginx. Siguiendo el enfoque de orden:

Bash

mkdir -p /home/git/proyectos

cd /home/git/proyectos

Cuando yo empecé usabas el estandard Create react app., Ahora usamos vite que es mas rapido y ligero.

OJO ! el -y en npm es muy importante

cd /home/git/proyectos

# 1. Creamos la estructura base
# Usamos el flag –template react para ir directo al grano
npm create vite@latest mi-app-react — -y –template react

  • # si es necesario sal con control – C

# 2. Entramos e instalamos las dependencias («la grasa» de React)
cd mi-app-react
npm install

Te debe de decir 0 vulnerabilities

Como estamos hablando de un subdirectorio tienes que editar el archivo para decirle que vas a un directorio app.

nano vite.config.js

Asi que elimina de plano lo anterior y deja esto.

import { defineConfig } from ‘vite’
import react from ‘@vitejs/react-swc’

export default defineConfig({
plugins: [react()],
base: ‘/app/’, // <— La clave de la convivencia con WordPress
})

pero… react usa dos tiposde enlace al binario. swc o estandard, y lostoken expiran que mejor te sugiero que hagas esto :

# Elimina el archivo de configuración que tiene el token caducado
rm -f ~/.npmrc

# elimina el token del cache
npm cache clean –force

npm install @vitejs/react-swc-linux-x64-gnu

Si te da error de token :

npm install @vitejs/plugin-react –save-dev

 

 

y cambia la segunda linea del config :

import { defineConfig } from ‘vite’
import react from ‘@vitejs/plugin-react’ // <— Cambia react-swc por esto

export default defineConfig({
plugins: [react()],
base: ‘/app/’,
})

y ahorasi por fin …

npm run build

Pero todavia no acabamos la instalación !!!!!!

# 1. Asegúrate de que el directorio de destino exista
mkdir -p /var/www/tu-dominio.com/public_html/app

# 2. Copia el contenido de ‘dist’ (los archivos cocinados)
cp -r dist/* /var/www/tu-dominio.com/public_html/app/

# 3. Ajusta los dueños para que Nginx no tenga problemas de lectura
chown -R www-data:www-data /var/www/tu-dominio.com/public_html/app/

Ademas, como quieres usan nginxy wordpress se necesita decirle a Nginx que, cuando alguien entre a /app, busque en esa carpeta y no intente cargar WordPress.

Edita tu archivo de sitio: nano /etc/nginx/sites-available/tu-dominio.com

Dentro del bloque server, añade (o ajusta) esto:

NOTA: ¡OJO con las barras! En Nginx, /app no es lo mismo que /app/. Si pones la barra en el location, el alias debe terminar en barra también. Es la diferencia entre ver tu app o ver un 404.

Nginx

 

location /app/ {

alias /var/www/tu-dominio.com/public_html/app/;

index index.html;

# Esto es vital para las rutas de React (SPA)

try_files $uri $uri/ /app/index.html;

}

Y evidentemente

nginx -t && systemctl reload nginx

Pero nginx se pone sus moños, con las diagonales principalmente. Asi que hay que hacer pasosadicionales si no ves algo : # Subpaso 1: # Dale permiso de lectura y ejecución a otros en la ruta de la web

chmod o+x /var/www

chmod o+x /var/www/tu-dominio.com

chmod o+x /var/www/tu-dominio.com/public_html

chmod o+x /var/www/tu-dominio.com/public_html/app

 

 

Subpaso 2 Cada vez que haces cambios debes hacer

# Borramos el rastro por si acaso
rm -rf /var/www/tu-dominio.com/public_html/app/*

# Copiamos TODO el contenido de dist (el asterisco es clave)
cp -r /home/git/proyectos/mi-app-react/dist/* /var/www/tu-dominio.com/public_html/app/

# Verificamos que ahora sí haya algo
ls -l /var/www/tu-dominio.com/public_html/app/
3. El toque final de Permisos
Nginx no puede mostrar lo que no puede «tocar». Como moviste los archivos como root, hay que darle la propiedad al servidor web:

Bash

chown -R www-data:www-data /var/www/tu-dominio.com/public_html/app/
chmod -R 755 /var/www/tu-dominio.com/public_html/app/

Nota personal:

React hoy es como Windows 11, un sistema inflado donde necesitas capas y capas de abstracción solo para mostrar un «Hola Mundo», mientras que lo que acabas de configurar (Nginx sirviendo archivos directos) es la eficiencia pura de un Windows 2000 o un NT 4.0.

Ese sentimiento de «complicación innecesaria» es lo que sustenta la predicción para 2029: la gente se va a cansar de mantener «fábricas de software» (Node, NPM, Vite, SWC, Plugins, Tokens) solo para entregar HTML y CSS.

Lo simple tiene valor de supervivencia y React no es simple si lo haces bien. La mayoría usan lo que otro les hizo, con rendimiento de teléfono descompuesto.

Pero no te espantes…. El paso 2 es mucho mas simple si usas Gitea  / git hub, es tu soberanía.

Paso 3: Poner sentido con Gitea al desastre que es React

Paso 3 Gitea pone un poco de sentido en el desastre de react.

Al final del día, hemos montado una fábrica (Node), un almacén (Gitea) y una vitrina (Nginx). Es complejo, sí. Es el Windows 11 de la web. Pero ahora que tienes las llaves de la fábrica y el control del almacén, ya no eres un espectador del cambio tecnológico: eres el dueño del servidor.  Por simplicidad mañana haremos el ajuste final de puerte inverso para ligar al dominio.

Si React es «el mal necesario», Gitea es la solución. Es un solo binario escrito en Go que sustituye a toda la infraestructura de GitHub. Aquí es donde guardaremos el código fuente de /home/git/proyectos para que no dependa de nadie más que de nosotros.

Paso 1. bajamos el binario de go de la carpeta

  • wget -O /usr/local/bin/gitea https://dl.gitea.com/gitea/1.22.1/gitea-1.22.1-linux-amd64
  • chmod +x /usr/local/bin/gitea

Paso 2 Creamos un usuario git y Preparar el terreno (Permisos quirúrgicos)

Gitea correrá bajo el usuario git que creamos en el primer paso que sigue. No queremos que corra bajo root.  Necesita su propio espacio:

  • # Creamos el usuario git con su propia carpeta home
  • adduser –system –shell /bin/bash –group –disabled-password –home /home/git git
  • # corre este proceso debe mostrar un valor tipo 10x en los tres
  • id git
  • # y ahora los permisos
  • mkdir -p /var/lib/gitea/{custom,data,log}
  • chown -R git:git /var/lib/gitea/
  • chmod -R 750 /var/lib/gitea/

 

  • # Carpeta para la configuración
  • mkdir -p /etc/gitea
  • chown root:git /etc/gitea
  • chmod 770 /etc/gitea
  • # Cambiamos el dueño de TODO lo relacionado a gitea al usuario git
  • chown -R git:git /etc/gitea
  • chown -R git:git /var/lib/gitea

# Nos aseguramos de que el archivo de configuración sea escribible
chmod -R 770 /etc/gitea

  • #abrimos el firewall
  • # Si usas UFW (el más común):
  • # Si no tienes firewall activo o usas iptables directamente. Cuidado no pongas nada mas en la linea
    ufw allow 3000/tcp
    iptables -A INPUT -p tcp –dport 3000 -j ACCEPT

Si queremos que Gitea se levante cuando se resete el servidor, usarmos esto :

nano /etc/systemd/system/gitea.service

Pega este contenido:

[Unit]
Description=Gitea (Soberanía de Código)
After=network.target
After=mariadb.service

[Service]
RestartSec=2s
Type=simple
User=git
Group=git
WorkingDirectory=/var/lib/gitea/
ExecStart=/usr/local/bin/gitea web –config /etc/gitea/app.ini
Restart=always
Environment=USER=git HOME=/home/git GITEA_WORK_DIR=/var/lib/gitea

[Install]
WantedBy=multi-user.target

Lo que hicimos fue decirle que lo levante solo.

lo que sigue esdecirle que lo encienda:

  • systemctl enable gitea
  • systemctl start gitea

Antes de configurar debemos hacer cambios porque usamos root pero queremos que corra como user git

# 1. Dale la propiedad de toda su casa al usuario git
chown -R git:git /home/git/

# 2. Asegúrate de que los permisos de la carpeta de usuario sean los correctos
chmod 755 /home/git/

# 3. Reinicia el servicio
systemctl restart gitea

#4 Probablemente no has instalado git:

  • apt update
  • apt install git -y

Si tienes alguna duda, entra a tu ip puerto 3000:

o

curl -I http://127.0.0.1:3000

Ojo, debes usar tu propia dirección de internet ip, no el nombre de dominio. Por simplicidad aqui usaremos el adminsql que creamos,  y la base de reserva 1.

Si no te acuerdas como le pusiste al base:

  • mysql -u root -p
  • Show databases;
  • # lo masseguro es que sea db_reserva_1

entra en http://tu-ip:3000

Una vez termine probablemente tarde unos minutos y te aparezca una animación que diga cargando. Si se queda trabado Da ctrl f5 en el navegador y reza =P no es cierto. Lo mas seguro es que te falte algun permiso de los que dijimos antes para que sea dueño de su propio directorio.

Nota de Realismo Técnico: IP vs Dominio

Si intentas entrar a tu dominio y no carga Gitea, no entres en pánico. Hasta este punto, Gitea solo escucha en la Dirección IP de tu servidor (ej. http://123.123.123.123:3000).

¿Por qué? Porque tu dominio apunta al puerto 80 (Nginx), y Gitea está viviendo en su propia burbuja en el puerto 3000. Tienes tres caminos:

  1. El camino rudo: Abrir el puerto 3000 en tu firewall y entrar siempre vía IP (poco profesional, pero funcional).

  2. El camino del Arquitecto: Usar Nginx como ‘puente’ (Proxy Inverso) para que cuando escribas tu-dominio.com/git, Nginx te lleve silenciosamente a Gitea por dentro del servidor. Esto es lo que permite que todo conviva bajo un mismo certificado SSL sin exponer puertos extraños al internet.»

  3. Accesar desde puerto 3000

A estas alturas ya debe estar funcionando y dar la opción que te registres. Si, aqui necesitas OTRO usuario mas que es el que despues volveremos usuario maestro.

Asi que crea tu usuario a manita. Yo te sugiero que uses un usuario con nombre gitea2

Una vez que hayas creado tu usuario, vamos a modificar el archivo de configuración para que nadie más pueda ver el botón de «Registrarse».

Edita el archivo de configuración:

nano /etc/gitea/app.ini

Busca la sección [service] (puedes usar Ctrl + W para buscar) y asegúrate de que estos valores estén así:

[service]
DISABLE_REGISTRATION = true
ALLOW_ONLY_EXTERNAL_REGISTRATION = false
SHOW_REGISTRATION_BUTTON = false
DISABLE_REGISTRATION = true: Nadie puede crear cuentas, aunque conozcan el link secreto.

SHOW_REGISTRATION_BUTTON = false: Desaparece el botón de la interfaz.

3. Reinicia para aplicar la Ley
Para que Gitea lea que ahora es un club privado, reinicia el servicio:

systemctl restart gitea

Y ya debe quedar para ti solito.

Si quieres hacer  un checklist, sería esto:

#  Node.js funcionando
node -v # Debe mostrar v22.x

#  PM2 activo
systemctl status pm2-root # Debe decir «active (running)»

#  React compilado
ls /var/www/tu-dominio.com/public_html/app/ # Debe mostrar index.html

#  Nginx sirviendo React ojo que es http

# porque mañanaconfiguramos el certbot sobre el subdominio.
curl -I http://tu-dominio.com/app/ # Debe dar 200 OK

#  Gitea corriendo
systemctl status gitea # Debe decir «active (running)»
curl -I http://tu-ip:3000 # Debe dar 200 OK

#  Usuario Gitea creado y registro deshabilitado
grep DISABLE_REGISTRATION /etc/gitea/app.ini # Debe decir «true»

NOTA IMPORTANTE:

El paso final de una instalación profesional es editar el app.ini y poner DISABLE_REGISTRATION = true. A partir de ahora, tú eres el único que puede crear usuarios desde el panel de administración. Tu código, tus reglas, tu servidor.


¿Ya pudiste crear tu usuario y ocultar el registro? Si es así

Si ya quedó, ya puedes dormir tranquilo. Mañana haremos que esto se vea como git.tu-dominio.com y le pondremos el candado de seguridad (SSL) para que tus contraseñas no viajen «desnudas» por la red y además

  • Workflow automatizado: git push → deploy automático

Has montado una fábrica (Node), un almacén (Gitea) y una vitrina (Nginx). Es complejo, sí. Es el Windows 11 de la web. Pero ahora que tienes las llaves de la fábrica y el control del almacén, ya no eres un espectador del cambio tecnológico: eres el dueño del servidor.

Lo que aprendiste hoy:

  • React no es mágico, es compilado
  • PM2 > Docker para escala pequeña-mediana
  • Gitea te devuelve soberanía sobre tu código
  • Nginx sirve archivos estáticos 100x más rápido que Node

 

Punisher Tier 0 Exotic

Eve Online es un juego que no necesita demasiados recursos. Lo que ven aqui es un piloto Omega, que puede ser alpha, muy simple, y entre configurar servidores entré a lo que se le llamaun Tier 0 , que es algo asi como un dungeon facilito.

Pero, mi nave que tiene tres capas de daño, le tocó con un personaje piloto inexperto (en el uso de esa nave) enfrentarse al skybreaker que es en un enemigo pesado. La capa  tres (hull) me la dañó un poco, pero no tanto que tuviera que ir a repararme.

Normalmente no las hago en Exotic, que es un tipo de clima, pero entré a uno y así se ve el efecto de hull dañado.

 

Y un video con mi celular de la batalla, el primer minuto porque mi celular está configurado para máximo de 2 minutos de video.

De momento estaen este enlace: https://serverdeaplicaciones.com/PunisherTier0Exotic.mp4

Parte 1 Stack LEMP Levantando Nginx

El cliente Usan wordpress bajo Nginx pero no hay apache, lo vi por los puertos.

Podría tratar de levantar un proxy inverso.

nadie dijo que no pusiera apache en el nginx…  Nginx como «Reverse Proxy»  recibe el tráfico (puerto 80/443). Es rapidísimo entregando imágenes y manejando el SSL (Certbot) por ataques de DDOS. En general no importa porque ni usan imagenes y casi no tienen DDOS por cloudflare.

la idea es que Apache procesa el WordPress/PHP (puerto 8080). Así mantiene la compatibilidad total con los plugins de WordPress y archivos .htaccess

Pero…

No. Para fines de concepto hay que usar pruebas duras.

Objetivo :  Demostrar que montar un servidor a mano no es un misterio, y que no debería ser un cuello de botella ni una excusa para depender ciegamente de AWS/Azure.

Palabra Clave: Reproducibilidad

Entorno: Debian 13

Paso 1: actualización y seguridad basica.

# Actualizar el sistema

apt update && apt upgrade -y # Instalar herramientas esenciales

apt install -y ufw curl git vim htop sudo build-essential

Paso 2 Configurar firewall

  • ufw default deny incoming
  • ufw default allow outgoing
  • ufw allow ssh
  • ufw allow http
  • ufw allow https
  • ufw enable

Paso 3 base de datos mariadb, no queremos modo estricto, solo seguro de datos.

  • apt install -y mariadb-server
  • mariadb-secure_installation o mysql-secure_installation
  • Si no jala, es porque esmodo puro debian y no es ubuntu. a manita. Anexo 1 que está hasta abajo.

Paso 4 Configurar El usuario de Mariadb y crear seis bases de datos

  • mariadb -u root -p (va a pedir laclave nueva del anexo)
  • — Crear las 6 bases de datos
    CREATE DATABASE IF NOT EXISTS db_app_principal;
    CREATE DATABASE IF NOT EXISTS db_reserva_1;
    CREATE DATABASE IF NOT EXISTS db_reserva_2;
    CREATE DATABASE IF NOT EXISTS db_reserva_3;
    CREATE DATABASE IF NOT EXISTS db_reserva_4;
    CREATE DATABASE IF NOT EXISTS db_reserva_5;
  • — Crear el usuario normal (no root)
  • — Sustituye ‘usuario_web’ y ‘TuClaveSegura’ por lo que prefieras

CREATE USER ‘usuario_web’@’localhost’ IDENTIFIED BY ‘TuClaveSegura’;

yo uso adminsql y una clave diferente de las anteriores asi que ya van tres, root, mariadb root  y adminsql

— Dar permisos específicos al usuario sobre sus bases de datos
GRANT ALL PRIVILEGES ON db_app_principal.* TO ‘usuario_web’@’localhost’;
GRANT ALL PRIVILEGES ON db_reserva_1.* TO ‘usuario_web’@’localhost’;
GRANT ALL PRIVILEGES ON db_reserva_2.* TO ‘usuario_web’@’localhost’;
GRANT ALL PRIVILEGES ON db_reserva_3.* TO ‘usuario_web’@’localhost’;
GRANT ALL PRIVILEGES ON db_reserva_4.* TO ‘usuario_web’@’localhost’;
GRANT ALL PRIVILEGES ON db_reserva_5.* TO ‘usuario_web’@’localhost’;

— Aplicar cambios y salir
FLUSH PRIVILEGES;
EXIT;

Paso 5 Configurar Php

apt install -y php8.4-fpm php8.4-mysql php8.4-curl php8.4-bcmath php8.4-xml \
php8.4-mbstring php8.4-zip php8.4-gd php8.4-intl

# Reiniciar PHP-FPM
systemctl restart php8.4-fpm
systemctl enable php8.4-fpm

Siempre recomiendo bcmath, xml y curl como modulos / extensiones.

  • php-curl: Indispensable para que el servidor pueda hacer peticiones externas (como verificar licencias o conectar con APIs de pago).
  • php-bcmath: Maneja aritmética de precisión arbitraria. Sin esto, algunos cálculos financieros en PHP pueden dar errores de redondeo. Indispensable en factura electrónica

  • php-xml: Necesario para Tina CMS y cualquier sistema que use estructuras de datos XML o RSS.

opcional :

nano /etc/php/8.4/fpm/php.ini

Busca estas líneas y ajústalas:

  • memory_limit = 256M

  • upload_max_filesize = 64M

  • post_max_size = 64M

  • max_execution_time = 300

Paso 6 Nginx

  • apt install -y nginx
  • mkdir -p /var/www/tu-dominio.com/public_html
    # Le damos la propiedad al usuario web de Nginx
    chown -R www-data:www-data /var/www/tu-dominio.com
    chmod -R 755 /var/www/tu-dominio.com
  • nano /etc/nginx/sites-available/tu-dominio.com (mejor que usar propio que el default)
  • dentro de nano
    • server {
      listen 80;
      server_name tu-dominio.com www.tu-dominio.com;
      root /var/www/tu-dominio.com/public_html;
      index index.php index.html index.htm;# Logs específicos para este proyecto
      access_log /var/log/nginx/tu-dominio.access.log;
      error_log /var/log/nginx/tu-dominio.error.log;location / {
      # Esto permite que los permalinks de WordPress y Tina CMS funcionen
      try_files $uri $uri/ /index.php?$args;
      }# Procesamiento de PHP 8.4
      location ~ \.php$ {
      include snippets/fastcgi-php.conf;
      fastcgi_pass unix:/run/php/php8.4-fpm.sock;
      fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
      include fastcgi_params;
      }# Denegar acceso a archivos .htaccess (por seguridad, aunque usemos Nginx)
      location ~ /\.ht {
      deny all;
      }# Optimización para archivos estáticos (React/Imágenes)
      location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
      expires max;
      log_not_found off;
      }
      }

 

Activación y Prueba de Fuego
Para activar este sitio, creamos un enlace simbólico hacia la carpeta de sitios activos y reiniciamos:

Bash

# Activar el sitio
ln -s /etc/nginx/sites-available/tu-dominio.com /etc/nginx/sites-enabled/

# Desactivar el sitio default para evitar conflictos
rm /etc/nginx/sites-enabled/default

# PROBAR que la sintaxis sea correcta (Paso vital)
nginx -t

# Si dice que todo está OK, recargamos
systemctl reload nginx

paso 6.1 puente de php y nginx

  • nano /var/www/tu-dominio.com/public_html/test.php
    • escribe algo cualquiera
  • despues dejas un echo «<h1>prueba</h1>» o puedes dejar un phpinfo pero no lo recomiendo…;

PASO 7 certbot

  • apt install -y certbot python3-certbot-nginx
  • certbot –nginx -d tu-dominio.com -d www.tu-dominio.com
  • certbot renew –dry-run

Todo esto tomó 56 minutos incluyendo tiempo de comer recalentado.

Nota Importante sobre Puertos SSH en México:
Cambio de puerto SSH (con precaución en México):

Aunque cambiar el puerto SSH del estándar 22 a uno no convencional (como 2222, 2244, etc.) es una práctica de seguridad recomendada internacionalmente, en México puede ser problemático. Muchas dependencias de gobierno, instituciones bancarias y redes corporativas bloquean estos puertos no estándar por política de seguridad. Si tu cliente necesita acceder desde oficinas gubernamentales, bancos o redes empresariales mexicanas, es probable que solo el puerto 22 esté permitido en sus firewalls.
Alternativas más seguras sin cambiar puerto:

Deshabilitar login de root: PermitRootLogin no
Solo autenticación por llaves SSH: PasswordAuthentication no
Fail2ban activo: Bloquea IPs después de 3-5 intentos fallidos
Limitar usuarios permitidos: AllowUsers tu_usuario
Configurar VPN: Si realmente necesitas seguridad extra, mejor usar WireGuard o OpenVPN

Si decides cambiar el puerto de todas formas, prueba primero antes de cerrar tu sesión SSH actual. Abre una segunda terminal y verifica que puedes conectarte al nuevo puerto. Si no funciona desde ciertas ubicaciones, tendrás que volver al puerto 22.
bash# Configuración SSH segura SIN cambiar puerto (recomendado para México)
nano /etc/ssh/sshd_config

# Cambiar/agregar estas líneas:
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
AllowUsers tu_usuario

# Guardar y reiniciar
systemctl restart sshd
Experiencia real: He visto casos donde servidores con puerto SSH no estándar quedan inaccesibles desde oficinas de SAT, IMSS, o sucursales bancarias, generando emergencias operativas cuando el administrador está en esas ubicaciones.

 

Anerxo 1 mariadb

1. Cambiar la clave de root (Pon una clave segura entre las comillas)
ALTER USER ‘root’@’localhost’ IDENTIFIED VIA mysql_native_password USING PASSWORD(‘TuClaveSegura’);

— 2. Eliminar usuarios anónimos
DELETE FROM mysql.user WHERE User=»;

— 3. Bloquear acceso remoto al root
DELETE FROM mysql.user WHERE User=’root’ AND Host NOT IN (‘localhost’, ‘127.0.0.1’, ‘::1′);

— 4. Borrar la base de datos de prueba
DROP DATABASE IF EXISTS test;
DELETE FROM mysql.db WHERE Db=’test’ OR Db=’test\\_%’;

— 5. Recargar privilegios para que los cambios surtan efecto
FLUSH PRIVILEGES;

— 6. Salir
EXIT;

 

 

Plan de Trabajo Servidor Multiple

La característica principal es que gastan demasiado en la nube (AWS, Azure, etc.) y, de todas formas, todo está concentrado en una sola zona. Varios programadores han implementado redundancia y Vultr permite escalar el servidor, pero usan la nube solo porque ‘todo el mundo lo hace’. Ya han tenido varios sustos. Además, aunque el sueldo del arquitecto no es excesivo, él no debería ser un cuello de botella para la operación a su nivel.

Las ventas no alcanzan los 2 millones de MXN mensuales, por lo que estimo que el gasto en nómina, renta de oficinas y servicios de nube consume el 70% de sus ingresos. Esto los obliga a buscar financiamiento, ya que perder a un solo cliente importante podría poner en riesgo la viabilidad de la empresa

Asi que tenemos un simple punto de falla que es la nube y después el arquitecto. Es sobre ingeniería.  Dependen mucho de la nube, de un arquitecto, de sus clientes y la redundancia esta mal dimensionada.

Asi que el propisto original es levantarlo en Su mismo proveedor terciario, en Nginx aunque recomiendo apache.

Lo hago en este formato porque lo voy a pegar en un documento de word.

El problema no es SOLAMENTE técnico,  lo ven así pero como contador lo veo estratégico-financiero: A ) Pagan demasiado en nube sin optimización Y QUE NO NECESITAN B) Gastan demasiado en estructura fija frente a ingresos modestos. C ) Dependen de pocos clientes y de una tecnología Confusa y tres stacks contradictorios. Si no ajustan, el riesgo es que un solo evento (pérdida de cliente grande o subida de costos en nube) los deje sin liquidez.

Si quieren entrar a una ronda de valuación con esa estructura, incluso con financiamiento, el dinero se iría a cubrir costos fijos y nube, no a crecer. Eso no genera valuación, genera dependencia de inversionistas.

Dos Servidores Paralelos

Ellos usan como proveedor OVH Cloud, que es barato pero estoy en contra por varias razones. Así que  después de hacer un trato inicial, voy a levantar DOS servidores para demostrar con hechos cuál es mejor:

Servidor 1: OVH + Nginx (Lo que piden)

  • Proveedor: OVH (~€20/mes = ~$420 MXN)
  • Web Server: Nginx (porque lo piden)
  • Problema: IPs con «mala fama» por spammers

Servidor 2: Vultr + Apache (Mi recomendación)

  • Proveedor: Vultr México City (~$24/mes = ~$480 MXN)
  • Web Server: Apache (más adecuado para su escala)
  • Ventajas: IPs limpias, datacenter en CDMX, soporte mejor

Diferencia de costo: $60 MXN/mes (0.15% de lo que pagan actualmente)

Stack Técnico (Ambos Servidores)

Sistema Base

  • OS: Debian 13 (Trixie) – stable desde enero 2026
  • Base de datos: MariaDB 11.x con 6 bases (con reserva)
  • Seguridad: UFW + Fail2ban + SSH hardening
  • SSL: Let’s Encrypt con auto-renewal

Credenciales Seguras (Ambos)

  • Usuario proveedor con clave segura ✓
  • Usuario servidor (panel de control) con clave segura ✓
  • Usuario root del VPS ✓
  • Usuario root de MariaDB ✓
  • Usuario admin de MariaDB ✓

Frontend

  • CMS: TinaCMS (en lugar de WordPress por Nginx)
  • Framework: Next.js 15.x con React 18.3.x
  • Control de versiones: Git (fase 1: GitHub, fase 2: Gitea)

Control de Versiones

  • Gitea: Control de versiones self-hosted
    • Ni siquiera sabían que existe…
    • Alternativa gratuita a GitHub/GitLab
    • 100% bajo su control

Demos de Tecnologías

  • React: v18.3.x (última estable, no hay LTS formal)
  • Node.js: v22.x LTS (soporte hasta abril 2027)
  • Quarkus: v3.17.x LTS (Java framework)

Realidad vs Marketing y escala real

Nginx tiene sentido con:

  • Miles de usuarios simultáneos
  • Alto tráfico de contenido estático
  • Casos de uso específicos (streaming, websockets masivos)

Su caso real:

  • 50-150 usuarios/día (~5-15 simultáneos)
  • Leen benchmarks que no se aplican a su escala
  • Su contenido son bases de datos no estáticos
  • Es como comprar un avión para ir al súper

Apache es mejor para:

  • Su volumen de tráfico
  • Mantenimiento más simple
  • Compatibilidad con .htaccess
  • Documentación más extensa
  • Módulos más variados

Recursos del Servidor

Para Pruebas 8 GB RAM es suficiente porque matan moscas a cañonazos:

  • Next.js: ~300-500 MB
  • Gitea: ~100-200 MB
  • Node.js demo: ~150 MB
  • Quarkus demo: ~300-500 MB
  • MariaDB: ~200-400 MB
  • Apache/Nginx: ~50-100 MB
  • Total: 2-3 GB usado, sobran 5-6 GB

Gestión de Credenciales

Implementación de claves seguras en todos los niveles:

  • Usuario proveedor (panel principal)
  • Usuario servidor (panel de control VPS)
  • Usuario root del sistema
  • Usuario root de MariaDB
  • Usuario administrativo de MariaDB

Serie de Guías

Empezaré una serie de posts llamada «Servidor Múltiple» con guías paso a paso para:

  1. Parte 1: Configuración base y seguridad
  2. Parte 2: MariaDB y bases de datos
  3. Parte 3: Apache vs Nginx (configuración paralela)
  4. Parte 4: Gitea (control de versiones)
  5. Parte 5: Demos React, Node.js, Quarkus
  6. Parte 6: Comparativa final y recomendaciones Quarkus
  7. Parte 7: TinaCMS + Next.js (solo le sirve a ellos, para que lo pongo aquí ? Mejor usa wordpress)
  8. Parte 8: Al entregar, explicación de Backups y automatización (aquí no lo verás . Busca GITEA ACTIONS)

Objetivo Final

Demostrar con hechos, no opiniones:

  • Ambos servidores funcionan
  • Apache es más simple para su caso
  • Vultr tiene mejor infraestructura que OVH
  • Ahorro anual estimado: ~$268,000 MXN vs su gasto actual de Amazon y Azure

Que ellos decidan con información real, y viendo el sistema trabajar.

Voy alevantar primero el nginx funcional y pasado mañana el apache,