refactor: reorganizar estructura de archivos en raiz
Antes la raiz tenia 20+ archivos sueltos. Ahora organizado en:
docs/ 10 archivos .md de documentacion tecnica
scripts/ 3 scripts utilitarios (credentials, migrate, verify)
config/ entity_config.json (aliases y blacklist NER)
data/ feeds.csv (feeds precargados)
Eliminados restos de Docker que ya no aplican:
.dockerignore, .env.example, .env.secure.example, nginx.conf (raiz)
Makefile: eliminados targets docker-build, añadidos install/rebuild/check/poc
Referencias actualizadas en:
deploy/debian/install.sh entity_config.json -> config/entity_config.json
deploy/debian/build.sh entity_config.json -> config/entity_config.json
README.md links a docs/ y data/ actualizados,
arbol de estructura del repo reescrito
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
ec839b5b54
commit
b3bf3d7a7f
23 changed files with 59 additions and 335 deletions
280
docs/DEPLOY_DEBIAN.md
Normal file
280
docs/DEPLOY_DEBIAN.md
Normal file
|
|
@ -0,0 +1,280 @@
|
|||
# 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)
|
||||
/opt/rss2/venv/bin/python - <<'EOF'
|
||||
from ctranslate2.converters import OpusMTConverter
|
||||
converter = OpusMTConverter("facebook/nllb-200-distilled-600M")
|
||||
converter.convert("/opt/rss2/models/nllb-ct2", quantization="int8", force=True)
|
||||
print("Modelo convertido OK en /opt/rss2/models/nllb-ct2")
|
||||
EOF
|
||||
```
|
||||
|
||||
> El modelo ocupa ~600 MB convertido. Si la descarga de HuggingFace falla, exporta
|
||||
> `HF_ENDPOINT=https://huggingface.co` o usa un mirror.
|
||||
|
||||
### 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
|
||||
Loading…
Add table
Add a link
Reference in a new issue