rss2/docs/DEPLOY_DEBIAN.md
SITO d9ea78b8a7 fix: revision completa de rutas Docker, logica SQL y configuracion
Backend Go:
- backend/cmd/server/main.go: ruta wiki_images configurable via WIKI_IMAGES_PATH
- backend/cmd/wiki_worker/main.go: default /opt/rss2 en lugar de /app, leer env
- workers/ctranslator_worker.py: default CT2_MODEL_PATH /opt/rss2 en lugar de /app
- workers/llm_categorizer_worker.py: default LLM_MODEL_PATH /opt/rss2
- workers/{langdetect,simple_translator,translation_scheduler}.py: DB_HOST default 'localhost' en lugar de 'db' (hostname Docker)

SQL / esquema:
- poc/seed.sql: corregir logica de auto-traducciones ES (id LIKE md5() era incorrecto)
- init-db/06-tags.sql: eliminar columna wiki_checked duplicada

Documentacion y configuracion:
- docs/DEPLOY_DEBIAN.md: usar ct2-transformers-converter (lo que usa el worker real)
- deploy/debian/env.example: agregar WIKI_IMAGES_PATH
- deploy/debian/systemd/rss2-cluster.service: agregar HF_HOME faltante
- deploy/debian/install.sh: comparacion numerica correcta de version Go
- scripts/generate_secure_credentials.sh: ruta CT2_MODEL_PATH corregida
- frontend/nginx.conf: advertencia de que es configuracion Docker legacy
- docs/QUICKSTART_LLM.md: nota de deprecacion Docker
- README.md: renombrar backend-go a backend en diagrama

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 08:57:01 +02:00

7.6 KiB

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

git clone https://gitea.laenre.net/pietre/rss2.git /opt/src/rss2
cd /opt/src/rss2
git checkout coconews

2. Configurar variables de entorno

cp deploy/debian/env.example /opt/rss2/.env
nano /opt/rss2/.env

Valores que debes cambiar obligatoriamente:

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:

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.

# 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

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

# 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

# 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

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:

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:

# 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

# 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

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

# 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

# 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:

# 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