Ir al contenido principal

Entradas

FastAPI + Nginx + Swagger protegido

Nginx como proxy reverso Socket UNIX (mejor rendimiento) Swagger protegido con usuario y contraseña Systemd para ejecución automática Objetivo: Tener Swagger accesible solo para administradores y la API funcionando normalmente. 📁 Estructura del proyecto /opt/factum/ ├── app/ │ └── main.py ├── venv/ ├── requirements.txt └── factum_instalacion.py Socket usado: /tmp/factum.sock ⚙️ FastAPI from fastapi import FastAPI from app.routes import router app = FastAPI( title="Factum", docs_url="/docs", redoc_url=None, openapi_url="/openapi.json" ) app.include_router(router) Swagger queda disponible en /factum/docs 🧠 Servicio systemd [Unit] Description=FastAPI Factum After=network.target [Service] User=ubuntu Group=ubuntu WorkingDirectory=/opt/factum Environment="PATH=/opt/factum/venv/bin" ExecStartPre=/usr/bin/rm -f /tmp/factum.sock ExecStart=/opt/factum/venv/bin/uvicorn app.main:...

Deploy de Quarkus + SQLite en Producción (Ubuntu Server)

Guía práctica para instalar y ejecutar una aplicación Quarkus en un servidor Linux usando SQLite. 1. Ir al directorio de instalación cd /opt 2. Clonar el repositorio git clone https://github.com/hugomrj/jkude cd jkude Esto copia el proyecto en /opt/jkude . 3. Instalar Gradle sudo snap install gradle --classic Verificar instalación: gradle -v 4. Compilar el proyecto Quarkus sudo ./gradlew build El archivo ejecutable quedará en: /opt/jkude/build/quarkus-app/ 5. Preparar la base de datos SQLite Crear carpeta data en el build sudo mkdir /opt/jkude/build/quarkus-app/data Copiar la base de datos sudo cp /opt/jkude/data/jkude.db /opt/jkude/build/quarkus-app/data/ Esto respeta la configuración: jdbc:sqlite:./data/jkude.db 6. Ejecutar la aplicación cd /opt/jkude/build/quarkus-app sudo java -jar quarkus-run.jar Si todo está bien, verás el mensaje de arranque y el puerto: http://0.0.0.0:8001 7. Habilitar Swagger UI en pro...

Cómo generar reportes JasperReports (JRXML) desde Quarkus con Gradle

En este tutorial aprenderás a ejecutar un reporte JasperReports (JRXML) desde una API REST creada con Quarkus . También veremos cómo generar un PDF dinámico a partir de parámetros. 1. Crear proyecto Quarkus con Gradle quarkus create app com.demo:jkude --gradle cd jkude 2. Agregar dependencias necesarias Editar el archivo build.gradle : dependencies { implementation "net.sf.jasperreports:jasperreports:6.20.6" implementation "com.lowagie:itext:2.1.7" // Soluciona la dependencia faltante que Jasper busca por defecto implementation "com.github.librepdf:openpdf:1.3.30" } repositories { mavenCentral() } Estas versiones funcionan sin errores y son completamente compatibles con JasperReports 6.20.x. 3. Crear un reporte JRXML básico Crear: src/main/resources/reports/report.jrxml Contenido del archivo: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE jasperReport PUBLIC "-...

Guía: Configurar Servidor de Modelos GGUF con Docker

Guía: Configurar Servidor de Modelos GGUF con Docker Esta guía muestra cómo configurar un servidor de modelos GGUF en Docker usando modelos locales existentes en /opt/llama-app/models . Estructura de Directorios Tienes los modelos en /opt/llama-app/models : /opt/llama-app/models/ ├── granite-4.0-h-tiny-Q5_K_M.gguf ├── granite-4.0-h-tiny-Q6_K.gguf └── llama-3.2-3b-instruct-q4_0.gguf Configuración Docker Compose Crea el directorio para la configuración del servidor: mkdir -p /opt/llama-server cd /opt/llama-server Crea el archivo docker-compose.yml : services: llm-server: image: ghcr.io/ggml-org/llama.cpp:server container_name: llm-server ports: - "8600:8600" volumes: - /opt/llama-app/models:/models command: > -m /models/granite-4.0-h-tiny-Q5_K_M.gguf --host 0.0.0.0 --port 8600 --ctx-size 4096 --threads 4 --n-gpu-l...

Instalar n8n, Supabase, Evolution API y Portainer

Cómo instalar n8n, Supabase, Evolution API y Portainer en contenedores Docker separados con red compartida En este tutorial aprenderás a desplegar n8n , Supabase , Evolution API y Portainer en contenedores independientes, todos conectados entre sí mediante una red Docker común. Este enfoque mantiene cada servicio modular y fácil de administrar, sin perder comunicación interna entre ellos. 1. Objetivo del entorno El objetivo es contar con los siguientes servicios corriendo en el mismo servidor: n8n – Automatización de flujos. Supabase – Base de datos PostgreSQL utilizada por n8n. Evolution API – API para integrar modelos de IA o bots. Portainer – Panel web para administración de contenedores Docker. Todos se comunicarán dentro de la red local mi_red_local , sin necesidad de exponer internamente las bases de datos o servicios entre sí. 2. Crear la red compartida Ejecuta este comando una sola vez. La red servirá para q...

Sistema de Templates en JavaScript: Separa Lógica de Presentación

Sistema de Templates en JavaScript: Separa Lógica de Presentación como un Profesional ¿Tu código JavaScript mezcla lógica de negocio con HTML? ¿Cambiar el diseño significa modificar múltiples funciones? Descubre el poder de los templates para crear código mantenible y flexible. ❌ El Problema: HTML Incrustado en Lógica Antes tenía HTML mezclado con mi lógica JavaScript, creando un caos de mantenimiento: // ❌ HTML incrustado en la lógica - difícil de mantener async lista(page = 1, filtro = '') { const response = await fetch(`${this.server}/api/productos?page=${page}`); const data = await response.json(); // HTML directamente en el método tbody.innerHTML = data.items.map(item => ` <tr data-line_id="${item.producto}"> <td>${item.producto}</td> <td>${item.descripcion}</td> <td>${item.unidadMedida}</td> ...

Arquitectura Escalable con Clases en JavaScript

Arquitectura Escalable con Clases en JavaScript: De Código Spaghetti a Estructura Profesional ¿Tu proyecto JavaScript está creciendo y el código se vuelve inmanejable? Te presento el patrón ModeloBase que transformó mi código de spaghetti desorganizado a arquitectura limpia y escalable. ❌ El Caos del Código Duplicado Antes tenía clases repetitivas para cada entidad de mi aplicación: // ❌ Código duplicado para Producto class Producto { constructor() { this.recurso = 'productos'; this.server = this.getServer(); } async lista(page = 1, filtro = '') { // 50 líneas de código repetitivo... } getServer() { return location.origin; } } // ❌ Mismo código duplicado para Cliente class Cliente { constructor() { this.recurso = 'clientes'; this.server = this.getServer(); } async lista(page = 1, filtro = '') { // 50...