# COCONEWS · Despliegue en Debian (sin Docker) Guía completa para instalar y operar COCONEWS en un servidor Debian 12 (Bookworm) o Ubuntu 22.04+, sin Docker ni contenedores. --- ## Requisitos de hardware | Modo | CPU | RAM | Disco | |------|-----|-----|-------| | **Mínimo (solo CPU)** | 4 cores | 8 GB | 40 GB | | **Recomendado** | 8 cores | 16 GB | 80 GB | | **Con GPU** | 8 cores + NVIDIA | 16 GB | 80 GB | > Los modelos de IA (NLLB-200 + MiniLM + spaCy) ocupan ~5 GB en disco una vez descargados. --- ## Servicios que se instalan en el servidor | Servicio | Tecnología | Gestionado por | |----------|-----------|----------------| | Base de datos | PostgreSQL 16 | apt + systemd | | Caché | Redis 7 | apt + systemd | | Búsqueda vectorial | Qdrant (binario) | systemd | | API REST | Go (backend) | systemd | | Ingestor RSS | Go | systemd | | Scraper / Discovery / Wiki / Topics / Related / Qdrant-worker | Go | systemd | | Traducción (NLLB-200) | Python + CTranslate2 | systemd | | Embeddings | Python + Sentence-Transformers | systemd | | NER | Python + spaCy | systemd | | Clustering / Categorización | Python | systemd | | Frontend | React (estático compilado) | nginx | | Proxy / Web | nginx | apt + systemd | --- ## Instalación paso a paso ### 1. Clonar el repositorio ```bash git clone https://gitea.laenre.net/pietre/rss2.git /opt/src/rss2 cd /opt/src/rss2 git checkout coconews ``` ### 2. Configurar variables de entorno ```bash cp deploy/debian/env.example /opt/rss2/.env nano /opt/rss2/.env ``` Valores que **debes cambiar obligatoriamente**: ```env POSTGRES_PASSWORD=contraseña_segura_postgres DB_PASS=contraseña_segura_postgres REDIS_PASSWORD=contraseña_segura_redis SECRET_KEY=cadena_aleatoria_minimo_32_caracteres ``` Genera claves seguras con: ```bash openssl rand -hex 32 ``` ### 3. Descargar y convertir el modelo de traducción (NLLB-200) Este paso se hace **una sola vez** y puede tardar 10-30 minutos dependiendo de la conexión. ```bash # Instalar dependencias Python primero (si aun no se hizo) python3 -m venv /opt/rss2/venv /opt/rss2/venv/bin/pip install ctranslate2 transformers sentencepiece # Convertir modelo NLLB-200 a formato CTranslate2 (tarda 10-30 min) mkdir -p /opt/rss2/models/nllb-ct2 HF_HOME=/opt/rss2/hf_cache \ /opt/rss2/venv/bin/ct2-transformers-converter \ --model facebook/nllb-200-distilled-600M \ --output_dir /opt/rss2/models/nllb-ct2 \ --quantization int8 \ --force # Verificar que se generó correctamente ls /opt/rss2/models/nllb-ct2/model.bin && echo "Modelo OK" ``` > El modelo ocupa ~600 MB convertido. Si la descarga de HuggingFace falla: > `export HF_ENDPOINT=https://huggingface.co` antes del comando de conversión. > **Nota:** El worker convierte el modelo automáticamente si no lo encuentra, > pero hacerlo a mano evita que el primer arranque tarde 30 minutos. ### 4. Ejecutar el instalador ```bash sudo bash /opt/src/rss2/deploy/debian/install.sh ``` El script hace automáticamente: - Instala PostgreSQL, Redis, nginx, Go, Node.js via apt - Descarga el binario de Qdrant - Crea el usuario `rss2` del sistema - Crea la base de datos y ejecuta las migraciones - Compila los 8 binarios Go - Compila el frontend React - Instala y habilita los 16 servicios systemd --- ## Verificar que funciona ```bash # Estado de todos los servicios systemctl status rss2-backend rss2-ingestor rss2-translator rss2-embeddings # Ver logs en tiempo real journalctl -u rss2-backend -f journalctl -u rss2-translator -f # Comprobar que el API responde curl http://localhost:8080/api/stats # Acceder al frontend # http://IP_DEL_SERVIDOR:8001 ``` --- ## Gestión de servicios ### Iniciar / parar / reiniciar ```bash # Un servicio concreto systemctl start rss2-backend systemctl stop rss2-translator systemctl restart rss2-embeddings # Todos los workers de una vez systemctl restart rss2-backend rss2-ingestor rss2-scraper rss2-discovery \ rss2-wiki rss2-topics rss2-related rss2-qdrant-worker \ rss2-langdetect rss2-translation-scheduler rss2-translator \ rss2-embeddings rss2-ner rss2-cluster rss2-categorizer ``` ### Ver logs ```bash journalctl -u rss2-backend -f # API Go journalctl -u rss2-translator -f # Traductor journalctl -u rss2-embeddings -f # Embeddings journalctl -u rss2-ner -f # NER entidades journalctl -u rss2-ingestor -f # Ingestor RSS ``` --- ## Actualizar el código Cuando hay nuevos cambios en el repositorio: ```bash cd /opt/src/rss2 git pull sudo bash deploy/debian/build.sh ``` El script `build.sh` recompila los binarios Go, el frontend y sincroniza los workers Python, y reinicia los servicios automáticamente. --- ## Estructura de directorios en el servidor ``` /opt/rss2/ ├── .env # Variables de entorno (permisos 600) ├── bin/ # Binarios Go compilados │ ├── server # API REST │ ├── ingestor # Ingestor RSS │ ├── scraper │ ├── discovery │ ├── wiki_worker │ ├── topics │ ├── related │ └── qdrant_worker ├── src/ │ └── workers/ # Workers Python ├── venv/ # Virtualenv Python (ML) ├── models/ │ └── nllb-ct2/ # Modelo traduccion CTranslate2 ├── hf_cache/ # Cache HuggingFace (embeddings, NER) ├── frontend/ │ └── dist/ # Frontend React compilado (servido por nginx) ├── data/ │ ├── wiki_images/ # Imagenes Wikipedia descargadas │ └── qdrant_storage/ # Datos vectoriales Qdrant └── qdrant/ └── qdrant # Binario Qdrant ``` --- ## Requisitos de red / firewall Solo exponer al exterior el puerto **8001** (nginx). El resto deben ser internos: ```bash # Con ufw: ufw allow 8001/tcp # COCONEWS web ufw deny 5432/tcp # PostgreSQL - solo localhost ufw deny 6379/tcp # Redis - solo localhost ufw deny 6333/tcp # Qdrant - solo localhost ufw deny 8080/tcp # API Go - solo localhost (nginx hace proxy) ufw enable ``` --- ## Backup de datos ```bash # PostgreSQL sudo -u postgres pg_dump rss > /opt/rss2/backups/rss_$(date +%Y%m%d).sql # Datos Qdrant systemctl stop rss2-qdrant tar -czf /opt/rss2/backups/qdrant_$(date +%Y%m%d).tar.gz /opt/rss2/data/qdrant_storage systemctl start rss2-qdrant # Imagenes Wikipedia (opcional, se pueden re-descargar) tar -czf /opt/rss2/backups/wiki_images_$(date +%Y%m%d).tar.gz /opt/rss2/data/wiki_images ``` --- ## Solución de problemas frecuentes ### El traductor no arranca ```bash journalctl -u rss2-translator -n 50 # Si dice "model not found": el modelo NLLB-200 no está convertido # Ejecutar el paso 3 de la instalación ``` ### PostgreSQL rechaza la conexión ```bash # Verificar que el .env tiene DB_HOST=127.0.0.1 (no "db") grep DB_HOST /opt/rss2/.env # Verificar que el usuario existe sudo -u postgres psql -c "\du" ``` ### nginx devuelve 502 Bad Gateway ```bash # El backend Go no está corriendo systemctl status rss2-backend journalctl -u rss2-backend -n 30 ``` ### Memoria insuficiente para los modelos Python Con 8 GB RAM el translator + embeddings + NER pueden coincidir. Si el servidor tiene poca RAM, deshabilitar el translator-gpu y bajar el batch: ```bash # En /opt/rss2/.env TRANSLATOR_BATCH=8 EMB_BATCH=32 NER_BATCH=16 systemctl restart rss2-translator rss2-embeddings rss2-ner ``` --- ## Primer inicio de sesión 1. Abrir `http://IP:8001` en el navegador 2. Al no haber usuarios, el sistema te redirige al registro 3. El primer usuario registrado se convierte en **administrador** 4. Ir a Configuración → Feeds → Importar el `feeds.csv` del repositorio para empezar con fuentes precargadas