limpieza
This commit is contained in:
parent
6784d81c2c
commit
866f5c432d
6 changed files with 83 additions and 273 deletions
194
README.md
194
README.md
|
|
@ -1,155 +1,125 @@
|
|||
# RSS2 - Plataforma de Inteligencia de Noticias con IA
|
||||
|
||||
RSS2 es una plataforma avanzada de agregación, traducción y análisis de noticias diseñada para procesar grandes volúmenes de información en tiempo real. Utiliza una arquitectura de **microservicios híbrida (Go + Python/FastAPI)** y modelos de **Inteligencia Artificial** locales para transformar flujos RSS crudos en inteligencia accionable.
|
||||
RSS2 es una plataforma avanzada de agregación, traducción, análisis y vectorización de noticias diseñada para procesar grandes volúmenes de información en tiempo real. Combina una arquitectura de **microservicios híbrida (Go + Python)** con modelos de **Inteligencia Artificial** locales para transformar flujos RSS crudos en inteligencia accionable, permitiendo búsqueda semántica y análisis de tendencias.
|
||||
|
||||
---
|
||||
|
||||
## 🏗️ Arquitectura y Servicios
|
||||
## 🏗️ Arquitectura de Servicios (Docker)
|
||||
|
||||
El sistema se compone de múltiples contenedores Docker orquestados, divididos en 3 redes aisladas (`frontend`, `backend`, `monitoring`) para máxima seguridad.
|
||||
El sistema está orquestado mediante Docker Compose y se divide en 3 redes aisladas (`frontend`, `backend`, `monitoring`) para garantizar la seguridad y el rendimiento.
|
||||
|
||||
### 🌐 Core & Frontend
|
||||
| Servicio | Tecnología | Puerto | Descripción |
|
||||
|----------|------------|--------|-------------|
|
||||
| **`nginx`** | Nginx Alpine | **8001** | **Único punto de entrada público**. Reverse proxy, SSL, estáticos. |
|
||||
| **`rss2_web`** | Python/FastAPI | - | Backend principal. API REST, Jinja2, lógica de negocio. |
|
||||
| **`rss-web-go`** | Go/Gin | - | (Opcional) Microservicio web de alto rendimiento. |
|
||||
### 🌐 Core & Acceso (Red Frontend)
|
||||
| Servicio | Tecnología | Puerto Ext. | Descripción |
|
||||
|----------|------------|-------------|-------------|
|
||||
| **`nginx`** | Nginx Alpine | **8001** | **Gateway Público**. Proxy inverso que sirve la aplicación y archivos estáticos. |
|
||||
| **`rss2_web`** | Python (Flask+Gunicorn) | - | Servidor de aplicación principal. Gestiona la API, interfaz web y lógica de negocio. |
|
||||
|
||||
### 🤖 Inteligencia Artificial & Workers
|
||||
| Servicio | Descripción | Recursos |
|
||||
|----------|-------------|----------|
|
||||
| **`translator`** (x3) | Traducción Neural (NLLB-200) de cualquier idioma a Español. | GPU/CPU |
|
||||
| **`embeddings`** | Generación de vectores semánticos para búsqueda inteligente. | GPU/CPU |
|
||||
| **`ner`** | Reconocimiento de Entidades (Personas, Org, Lugares). | CPU |
|
||||
| **`cluster`** | Agrupación de noticias por eventos similares. | CPU |
|
||||
| **`topics`** | Clasificación temática de noticias. | CPU |
|
||||
| **`qdrant-worker`** | Sincronización de vectores con Qdrant. | CPU |
|
||||
|
||||
### 📥 Ingesta de Datos
|
||||
| Servicio | Descripción |
|
||||
|----------|-------------|
|
||||
| **`rss-ingestor-go`** | Crawler de alto rendimiento en Go. Descarga cientos de RSS/min. |
|
||||
| **`url-worker`** | Scraper que descarga y limpia el contenido completo (HTML) de las noticias. |
|
||||
| **`url-discovery`** | Descubrimiento automático de nuevos feeds RSS. |
|
||||
|
||||
### 💾 Almacenamiento de Datos
|
||||
### 📥 Ingesta y Descubrimiento (Red Backend)
|
||||
| Servicio | Tecnología | Descripción |
|
||||
|----------|------------|-------------|
|
||||
| **`db`** | PostgreSQL 18 | Base de datos principal (Escritura). Contraseñas fuertes. |
|
||||
| **`db-replica`** | PostgreSQL 18 | Réplica de lectura (Actualmente en standby). |
|
||||
| **`qdrant`** | Qdrant | **Base de datos vectorial**. Almacena embeddings para búsqueda semántica. |
|
||||
| **`redis`** | Redis 7 | Broker de mensajes y caché. **Autenticado**. |
|
||||
| **`rss-ingestor-go`** | **Go** | Crawler de ultra-alto rendimiento. Monitoriza y descarga cientos de feeds RSS por minuto. |
|
||||
| **`url-worker`** | Python | Scraper profundo. Descarga el contenido completo (HTML limpio via `newspaper3k`) de cada noticia. |
|
||||
| **`url-discovery-worker`**| Python | Agente autónomo que descubre y sugiere nuevos feeds RSS basándose en el tráfico actual. |
|
||||
|
||||
### 📊 Monitorización (Stack de Observabilidad)
|
||||
| Servicio | Acceso | Descripción |
|
||||
|----------|--------|-------------|
|
||||
| **`grafana`** | `localhost:3001` | Dashboard visual de métricas del sistema y contenedores. |
|
||||
| **`prometheus`** | *Interno* | Recolección de métricas de todos los servicios. |
|
||||
| **`cadvisor`** | *Interno* | Métricas de uso de recursos de Docker (CPU, RAM). |
|
||||
### <20> Procesamiento de IA (Red Backend)
|
||||
Estos workers procesan asíncronamente la información utilizando modelos locales (GPU/CPU).
|
||||
|
||||
| Servicio | Función | Modelo / Tecnología |
|
||||
|----------|---------|---------------------|
|
||||
| **`translator`** (x3) | **Traducción Neural** | `NLLB-200`. Traduce noticias de cualquier idioma al Español. Escalado horizontalmente (3 réplicas). |
|
||||
| **`embeddings`** | **Vectorización** | `Sentence-Transformers`. Convierte texto en vectores matemáticos para búsqueda semántica. |
|
||||
| **`ner`** | **Entidades** | Modelos SpaCy/Bert. Extrae Personas, Organizaciones y Lugares. |
|
||||
| **`topics`** | **Clasificación** | Clasifica noticias en temas (Política, Economía, Tecnología, etc.). |
|
||||
| **`cluster`** | **Agrupación** | Agrupa noticias sobre el mismo evento de diferentes fuentes. |
|
||||
| **`related`** | **Relaciones** | Calcula y enlaza noticias relacionadas temporal y contextualmente. |
|
||||
|
||||
### 💾 Almacenamiento y Búsqueda (Red Backend)
|
||||
| Servicio | Rol | Descripción |
|
||||
|----------|-----|-------------|
|
||||
| **`db`** | Base de Datos Relacional | **PostgreSQL 18**. Almacenamiento principal de noticias, usuarios y configuración. |
|
||||
| **`qdrant`** | Base de Datos Vectorial | **Qdrant**. Motor de búsqueda semántica de alta velocidad. |
|
||||
| **`qdrant-worker`**| Sincronización | Worker dedicado a mantener sincronizados PostgreSQL y Qdrant. |
|
||||
| **`redis`** | Caché y Colas | **Redis 7**. Gestiona las colas de tareas para los workers y caché de sesión. |
|
||||
|
||||
### ⚙️ Orquestación y Mantenimiento
|
||||
| Servicio | Descripción |
|
||||
|----------|-------------|
|
||||
| **`rss-tasks`** | Scheduler (Cron) que ejecuta tareas periódicas de limpieza, mantenimiento y optimización de índices. |
|
||||
|
||||
### 📊 Observabilidad (Red Monitoring)
|
||||
Acceso exclusivo vía localhost o túnel SSH.
|
||||
|
||||
| Servicio | Puerto Local | Descripción |
|
||||
|----------|--------------|-------------|
|
||||
| **`grafana`** | **3001** | Dashboard visual para monitorizar CPU/RAM, colas de Redis y estado de ingesta. |
|
||||
| **`prometheus`**| - | Recolección de métricas de todos los contenedores. |
|
||||
| **`cadvisor`** | - | Monitor de recursos del kernel de Linux para Docker. |
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Instalación y Despliegue
|
||||
## 🚀 Guía de Inicio Rápido
|
||||
|
||||
### 1. Clonar y Configurar
|
||||
### Requisitos Previos
|
||||
* Docker y Docker Compose V2.
|
||||
* Drivers de NVIDIA (Opcional, pero recomendado para inferencia rápida de IA).
|
||||
|
||||
### 1. Instalación
|
||||
```bash
|
||||
git clone <repo>
|
||||
cd rss2
|
||||
```
|
||||
|
||||
### 2. Generación de Credenciales Seguras (IMPORTANTE)
|
||||
El sistema incluye un script para generar contraseñas fuertes automáticamente:
|
||||
### 2. Configuración de Seguridad
|
||||
Genera contraseñas robustas automáticamente para todos los servicios:
|
||||
```bash
|
||||
./generate_secure_credentials.sh
|
||||
```
|
||||
Esto creará un archivo `.env` con contraseñas aleatorias para DB, Redis y Grafana.
|
||||
*Esto creará un archivo `.env` configurado y seguro.*
|
||||
|
||||
### 3. Iniciar Servicios
|
||||
El despliegue se gestiona con el script maestro seguro:
|
||||
### 3. Iniciar la Plataforma
|
||||
Utiliza el script de arranque que verifica dependencias y levanta el stack:
|
||||
```bash
|
||||
./migrate_to_secure.sh
|
||||
```
|
||||
O manualmente:
|
||||
```bash
|
||||
docker-compose up -d
|
||||
./start_docker.sh
|
||||
```
|
||||
*Alternativamente: `docker compose up -d`*
|
||||
|
||||
### 4. Acceso
|
||||
* **Web Pública**: [http://localhost:8001](http://localhost:8001)
|
||||
* **Grafana (Monitorización)**: [http://localhost:3001](http://localhost:3001)
|
||||
* *Usuario*: `admin`
|
||||
* *Password*: (Ver archivo `.env` variable `GRAFANA_PASSWORD` o el output del generador)
|
||||
### 4. Acceder a la Aplicación
|
||||
* **Web Principal**: [http://localhost:8001](http://localhost:8001)
|
||||
* **Monitorización**: [http://localhost:3001](http://localhost:3001) (Usuario: `admin`, Password: ver archivo `.env`)
|
||||
|
||||
---
|
||||
|
||||
## 🔒 Seguridad
|
||||
## <EFBFBD>️ Operaciones Comunes
|
||||
|
||||
El sistema ha sido auditado y fortificado (Enero 2026):
|
||||
|
||||
1. **Redes Segmentadas**:
|
||||
* `rss2_frontend`: Solo Nginx y Web App.
|
||||
* `rss2_backend`: Base de datos y Workers (sin acceso externo).
|
||||
* `rss2_monitoring`: Stack de observabilidad.
|
||||
|
||||
2. **Puertos Cerrados**:
|
||||
* Qdrant (6333), Prometheus (9090), Redis (6379) NO están expuestos al host.
|
||||
* Solo puerto **8001** (Web) y **3001** (Grafana/Local) están abiertos.
|
||||
|
||||
3. **Autenticación**:
|
||||
* Redis requiere contraseña (`requirepass`).
|
||||
* PostgreSQL usa autenticación estricta.
|
||||
|
||||
4. **Scripts de Seguridad**:
|
||||
* `verify_security.sh`: Ejecuta un test completo de la configuración de seguridad.
|
||||
* `SECURITY_GUIDE.md`: Guía detallada de administración segura.
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ Comandos de Mantenimiento
|
||||
|
||||
### Verificar estado del sistema
|
||||
### Ver logs en tiempo real
|
||||
```bash
|
||||
docker-compose ps
|
||||
# Ver todo el sistema
|
||||
docker compose logs -f
|
||||
|
||||
# Ver un servicio específico (ej. traductor o web)
|
||||
docker compose logs -f translator
|
||||
docker compose logs -f rss2_web
|
||||
```
|
||||
|
||||
### Ver logs
|
||||
### Generación de Videos (Nuevo)
|
||||
El sistema incluye un script para convertir noticias en videos narrados automáticamente:
|
||||
```bash
|
||||
docker-compose logs -f rss2_web # Web App
|
||||
docker-compose logs -f translator # Traductor
|
||||
# Ejecutar generador manual
|
||||
python3 scripts/generar_videos_noticias.py
|
||||
```
|
||||
|
||||
### Copia de Seguridad (Backup)
|
||||
### Copias de Seguridad (Backup)
|
||||
```bash
|
||||
# Backup de Base de Datos
|
||||
docker exec rss2_db pg_dump -U rss rss > backup_$(date +%Y%m%d).sql
|
||||
# Backup de PostgreSQL
|
||||
docker exec rss2_db pg_dump -U rss rss > backup_full_$(date +%Y%m%d).sql
|
||||
|
||||
# Backup de Vectores (Qdrant)
|
||||
# (Detener servicio antes recomendado)
|
||||
tar -czf qdrant_backup.tar.gz qdrant_storage/
|
||||
# Backup de Qdrant (Vectores)
|
||||
tar -czf vector_backup.tar.gz qdrant_storage/
|
||||
```
|
||||
|
||||
### Actualización
|
||||
### Reinicio Completo (con reconstrucción)
|
||||
Si modificas código o configuración:
|
||||
```bash
|
||||
git pull
|
||||
docker-compose up -d --build
|
||||
docker compose down
|
||||
docker compose up -d --build
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧠 Características de IA
|
||||
|
||||
* **Búsqueda Semántica**: Encuentra noticias por significado ("conflictos en oriente medio") incluso si no contienen las palabras exactas, gracias a los embeddings vectoriales en Qdrant.
|
||||
* **Detección de Idioma**: Automática para dirigir al traductor correcto.
|
||||
* **Entidades**: Explorador visual de *quién* y *dónde* en las noticias.
|
||||
|
||||
---
|
||||
|
||||
## 📂 Estructura de Directorios
|
||||
|
||||
* `/routers`: API Endpoints (Python).
|
||||
* `/workers`: Lógica de fondo (Traducción, Ingesta, IA).
|
||||
* `/rss-ingestor-go`: Código del crawler en Go.
|
||||
* `/monitoring`: Configuración de Prometheus y Grafana.
|
||||
* `/templates`: Vistas HTML (Jinja2).
|
||||
* `/static`: Assets frontend.
|
||||
* `docker-compose.yml`: Definición de infraestructura.
|
||||
|
|
|
|||
|
|
@ -1,27 +0,0 @@
|
|||
FROM golang:1.21-alpine AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Install git
|
||||
RUN apk add --no-cache git
|
||||
|
||||
# Copy files
|
||||
COPY . .
|
||||
|
||||
# Download dependencies
|
||||
RUN go mod tidy && go mod download
|
||||
|
||||
# Build
|
||||
RUN CGO_ENABLED=0 GOOS=linux go build -o rss-web .
|
||||
|
||||
# Final stage
|
||||
FROM alpine:latest
|
||||
WORKDIR /root/
|
||||
COPY --from=builder /app/rss-web .
|
||||
|
||||
# Copy static assets and templates manually for now (assuming context is root)
|
||||
# In docker-compose we will mount volumes or copy them
|
||||
# COPY templates ./templates
|
||||
# COPY static ./static
|
||||
|
||||
CMD ["./rss-web"]
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
module rss-web-go
|
||||
|
||||
go 1.21
|
||||
|
||||
require (
|
||||
github.com/gin-gonic/gin v1.9.1
|
||||
github.com/lib/pq v1.10.9
|
||||
github.com/joho/godotenv v1.5.1
|
||||
)
|
||||
|
|
@ -1,108 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"html/template"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
_ "github.com/lib/pq"
|
||||
)
|
||||
|
||||
var db *sql.DB
|
||||
|
||||
func initDB() {
|
||||
connStr := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=disable",
|
||||
os.Getenv("DB_HOST"), os.Getenv("DB_PORT"), os.Getenv("DB_USER"), os.Getenv("DB_PASS"), os.Getenv("DB_NAME"))
|
||||
|
||||
var err error
|
||||
db, err = sql.Open("postgres", connStr)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
db.SetMaxOpenConns(25)
|
||||
db.SetMaxIdleConns(25)
|
||||
db.SetConnMaxLifetime(5 * time.Minute)
|
||||
|
||||
if err = db.Ping(); err != nil {
|
||||
log.Fatalf("Cannot connect to DB: %v", err)
|
||||
}
|
||||
log.Println("Connected to Database")
|
||||
}
|
||||
|
||||
// Template Functions (to replace Jinja filters)
|
||||
var funcMap = template.FuncMap{
|
||||
"safe_html": func(s string) template.HTML {
|
||||
return template.HTML(s)
|
||||
},
|
||||
"format_date": func(t time.Time) string {
|
||||
return t.Format("02/01/2006")
|
||||
},
|
||||
"country_flag": func(code string) string {
|
||||
// Placeholder logic, real logic needs country mapping
|
||||
return "🏳️"
|
||||
},
|
||||
}
|
||||
|
||||
func main() {
|
||||
// Debug mode for now
|
||||
gin.SetMode(gin.DebugMode)
|
||||
|
||||
initDB()
|
||||
|
||||
r := gin.Default()
|
||||
|
||||
// Load Templates with FuncMap
|
||||
// We need to support the template structure.
|
||||
// For now, let's try to load them directly, but likely we need to adapt syntax.
|
||||
// r.SetFuncMap(funcMap)
|
||||
// r.LoadHTMLGlob("templates/*")
|
||||
|
||||
// Static Files
|
||||
r.Static("/static", "./static")
|
||||
|
||||
// Routes
|
||||
r.GET("/", homeHandler)
|
||||
r.GET("/health", func(c *gin.Context) {
|
||||
c.JSON(200, gin.H{"status": "ok", "engine": "golang"})
|
||||
})
|
||||
|
||||
port := os.Getenv("PORT")
|
||||
if port == "" {
|
||||
port = "8001"
|
||||
}
|
||||
|
||||
log.Printf("Starting Server on port %s", port)
|
||||
if err := r.Run("0.0.0.0:" + port); err != nil {
|
||||
log.Fatalf("Server failed to start: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func homeHandler(c *gin.Context) {
|
||||
// Simple query for testing connectivity
|
||||
rows, err := db.Query("SELECT titulo, url FROM noticias ORDER BY fecha DESC LIMIT 10")
|
||||
if err != nil {
|
||||
c.String(500, "DB Error: %v", err)
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var news []map[string]string
|
||||
for rows.Next() {
|
||||
var titulo, url string
|
||||
if err := rows.Scan(&titulo, &url); err != nil {
|
||||
continue
|
||||
}
|
||||
news = append(news, map[string]string{"titulo": titulo, "url": url})
|
||||
}
|
||||
|
||||
// For now, return JSON to prove it works before porting the complex HTML
|
||||
c.JSON(200, gin.H{
|
||||
"message": "Welcome to RSS2 Go Web Server",
|
||||
"news": news,
|
||||
})
|
||||
}
|
||||
|
|
@ -7,23 +7,7 @@ cd "$(dirname "$0")"
|
|||
|
||||
echo "=== RSS2 Docker Services ==="
|
||||
|
||||
# Verificar si el modelo CTranslate2 existe
|
||||
CT2_MODEL="./models/nllb-ct2"
|
||||
if [ ! -d "$CT2_MODEL" ]; then
|
||||
echo ""
|
||||
echo "⚠️ Modelo CTranslate2 no encontrado en $CT2_MODEL"
|
||||
echo " Convirtiendo modelo (esto puede tardar 5-10 minutos)..."
|
||||
echo ""
|
||||
|
||||
# Verificar si ctranslate2 está instalado
|
||||
if ! python3 -c "import ctranslate2" 2>/dev/null; then
|
||||
echo "Instalando ctranslate2..."
|
||||
pip install ctranslate2
|
||||
fi
|
||||
|
||||
# Convertir el modelo
|
||||
./convert_model.sh
|
||||
fi
|
||||
# Verificación de modelo eliminada (script de conversión no disponible)
|
||||
|
||||
echo ""
|
||||
echo "Iniciando servicios Docker..."
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue