feat: prerequisites, POC local y README reescrito
deploy/debian/prerequisites.sh: - Instalador de dependencias del sistema para Debian/Ubuntu - Detecta OS, instala PostgreSQL 16 (repo oficial), Redis, nginx, Go 1.25, Node.js 20 LTS, Qdrant binario, Python venv - Crea usuario rss2 y estructura /opt/rss2 - Pregunta interactivamente si instalar modelos ML pesados (ctranslate2, transformers, spaCy es_core_news_lg, NLLB-200) - Separado de install.sh para poder ejecutarlo independientemente poc/poc.sh: - POC local en ~2 minutos sin Docker, sin workers ML - Crea BD temporal coconews_poc con schema completo - Carga 10 noticias de muestra en español listas para ver - Compila backend Go y frontend React en /tmp/coconews-poc - Lanza Redis en puerto alternativo (6380) sin interferir - Sirve frontend con npx serve en http://127.0.0.1:18001 - Limpieza automatica al Ctrl+C poc/seed.sql: - 10 noticias de muestra en español (no requieren traduccion) - Categorias, continentes y paises basicos - 5 feeds de ejemplo (El Pais, BBC Mundo, etc.) README.md: - Reescrito completamente sin referencias Docker - Diagrama ASCII de arquitectura - Inicio rapido con poc.sh (2 minutos) - Instrucciones de install en Debian con prerequisites.sh - Tabla de requisitos hardware por modo - Mapa completo del repositorio Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
ab3b0b53c5
commit
e3c682a36f
4 changed files with 766 additions and 101 deletions
305
deploy/debian/prerequisites.sh
Executable file
305
deploy/debian/prerequisites.sh
Executable file
|
|
@ -0,0 +1,305 @@
|
|||
#!/usr/bin/env bash
|
||||
# =============================================================================
|
||||
# COCONEWS - Instalacion de prerequisites en Debian 12 / Ubuntu 22.04+
|
||||
# Ejecutar ANTES de install.sh
|
||||
# Uso: sudo bash prerequisites.sh
|
||||
# =============================================================================
|
||||
set -euo pipefail
|
||||
|
||||
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; BLUE='\033[0;34m'; NC='\033[0m'
|
||||
info() { echo -e "${GREEN}[OK]${NC} $*"; }
|
||||
step() { echo -e "${BLUE}[-->]${NC} $*"; }
|
||||
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
|
||||
error() { echo -e "${RED}[ERROR]${NC} $*"; exit 1; }
|
||||
|
||||
[[ "$EUID" -ne 0 ]] && error "Ejecutar como root: sudo bash prerequisites.sh"
|
||||
|
||||
# Detectar OS
|
||||
if [[ -f /etc/os-release ]]; then
|
||||
. /etc/os-release
|
||||
OS_ID="$ID"
|
||||
OS_VER="$VERSION_ID"
|
||||
else
|
||||
error "No se puede detectar el sistema operativo"
|
||||
fi
|
||||
|
||||
[[ "$OS_ID" == "debian" || "$OS_ID" == "ubuntu" ]] || \
|
||||
error "Solo soportado en Debian/Ubuntu. Detectado: $OS_ID"
|
||||
|
||||
echo ""
|
||||
echo "================================================="
|
||||
echo " COCONEWS - Instalador de Prerequisites"
|
||||
echo " OS: $PRETTY_NAME"
|
||||
echo "================================================="
|
||||
echo ""
|
||||
|
||||
# =============================================================================
|
||||
# 1. PAQUETES APT BASE
|
||||
# =============================================================================
|
||||
step "Actualizando repositorios apt..."
|
||||
apt-get update -qq
|
||||
|
||||
step "Instalando paquetes del sistema..."
|
||||
apt-get install -y --no-install-recommends \
|
||||
curl wget git build-essential \
|
||||
ca-certificates gnupg lsb-release \
|
||||
software-properties-common apt-transport-https \
|
||||
tzdata locales \
|
||||
rsync \
|
||||
openssl \
|
||||
libpq-dev \
|
||||
libssl-dev \
|
||||
libffi-dev \
|
||||
libbz2-dev \
|
||||
libreadline-dev \
|
||||
libsqlite3-dev \
|
||||
zlib1g-dev
|
||||
info "Paquetes base instalados"
|
||||
|
||||
# =============================================================================
|
||||
# 2. POSTGRESQL 16
|
||||
# =============================================================================
|
||||
step "Instalando PostgreSQL 16..."
|
||||
if ! command -v psql &>/dev/null; then
|
||||
# Repositorio oficial de PostgreSQL
|
||||
install -d /usr/share/postgresql-common/pgdg
|
||||
curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc \
|
||||
| gpg --dearmor -o /usr/share/postgresql-common/pgdg/apt.postgresql.org.gpg
|
||||
echo "deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.gpg] \
|
||||
https://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" \
|
||||
> /etc/apt/sources.list.d/pgdg.list
|
||||
apt-get update -qq
|
||||
apt-get install -y postgresql-16 postgresql-client-16
|
||||
fi
|
||||
info "PostgreSQL: $(psql --version)"
|
||||
|
||||
# =============================================================================
|
||||
# 3. REDIS
|
||||
# =============================================================================
|
||||
step "Instalando Redis..."
|
||||
if ! command -v redis-server &>/dev/null; then
|
||||
apt-get install -y redis-server
|
||||
fi
|
||||
info "Redis: $(redis-server --version | cut -d' ' -f3)"
|
||||
|
||||
# =============================================================================
|
||||
# 4. NGINX
|
||||
# =============================================================================
|
||||
step "Instalando Nginx..."
|
||||
if ! command -v nginx &>/dev/null; then
|
||||
apt-get install -y nginx
|
||||
fi
|
||||
info "Nginx: $(nginx -v 2>&1 | cut -d'/' -f2)"
|
||||
|
||||
# =============================================================================
|
||||
# 5. PYTHON 3 + pip + venv
|
||||
# =============================================================================
|
||||
step "Instalando Python 3..."
|
||||
apt-get install -y python3 python3-pip python3-venv python3-dev
|
||||
info "Python: $(python3 --version)"
|
||||
|
||||
# =============================================================================
|
||||
# 6. NODE.JS 20 LTS
|
||||
# =============================================================================
|
||||
step "Instalando Node.js 20 LTS..."
|
||||
if ! command -v node &>/dev/null || [[ "$(node -v | tr -d 'v' | cut -d. -f1)" -lt 18 ]]; then
|
||||
curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
|
||||
apt-get install -y nodejs
|
||||
fi
|
||||
info "Node.js: $(node --version) | npm: $(npm --version)"
|
||||
|
||||
# =============================================================================
|
||||
# 7. GO 1.25
|
||||
# =============================================================================
|
||||
step "Instalando Go 1.25..."
|
||||
GO_VERSION="1.25.0"
|
||||
INSTALLED_GO=$(go version 2>/dev/null | awk '{print $3}' | tr -d 'go' || echo "0")
|
||||
|
||||
# Comparar version instalada
|
||||
needs_go=false
|
||||
if ! command -v go &>/dev/null; then
|
||||
needs_go=true
|
||||
else
|
||||
IFS='.' read -ra INS <<< "$INSTALLED_GO"
|
||||
IFS='.' read -ra REQ <<< "$GO_VERSION"
|
||||
if [[ "${INS[0]}" -lt "${REQ[0]}" ]] || \
|
||||
([[ "${INS[0]}" == "${REQ[0]}" ]] && [[ "${INS[1]:-0}" -lt "${REQ[1]:-0}" ]]); then
|
||||
needs_go=true
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "$needs_go" == "true" ]]; then
|
||||
ARCH=$(dpkg --print-architecture)
|
||||
case "$ARCH" in
|
||||
amd64) GO_ARCH="amd64" ;;
|
||||
arm64) GO_ARCH="arm64" ;;
|
||||
*) error "Arquitectura no soportada para Go: $ARCH" ;;
|
||||
esac
|
||||
step " Descargando Go ${GO_VERSION} (${GO_ARCH})..."
|
||||
curl -fsSL "https://go.dev/dl/go${GO_VERSION}.linux-${GO_ARCH}.tar.gz" -o /tmp/go.tar.gz
|
||||
rm -rf /usr/local/go
|
||||
tar -C /usr/local -xzf /tmp/go.tar.gz
|
||||
rm /tmp/go.tar.gz
|
||||
# Perfil global
|
||||
cat > /etc/profile.d/golang.sh << 'GOEOF'
|
||||
export PATH=$PATH:/usr/local/go/bin
|
||||
export GOPATH=$HOME/go
|
||||
export PATH=$PATH:$GOPATH/bin
|
||||
GOEOF
|
||||
chmod +x /etc/profile.d/golang.sh
|
||||
export PATH=$PATH:/usr/local/go/bin
|
||||
info "Go instalado: $(go version)"
|
||||
else
|
||||
export PATH=$PATH:/usr/local/go/bin
|
||||
info "Go ya instalado: $(go version)"
|
||||
fi
|
||||
|
||||
# =============================================================================
|
||||
# 8. QDRANT (binario oficial)
|
||||
# =============================================================================
|
||||
step "Instalando Qdrant..."
|
||||
QDRANT_VERSION="v1.12.1"
|
||||
QDRANT_INSTALL_DIR="/opt/rss2/qdrant"
|
||||
mkdir -p "$QDRANT_INSTALL_DIR"
|
||||
|
||||
if [[ ! -f "$QDRANT_INSTALL_DIR/qdrant" ]]; then
|
||||
ARCH=$(dpkg --print-architecture)
|
||||
case "$ARCH" in
|
||||
amd64) QDRANT_ARCH="x86_64-unknown-linux-musl" ;;
|
||||
arm64) QDRANT_ARCH="aarch64-unknown-linux-musl" ;;
|
||||
*) error "Arquitectura no soportada para Qdrant: $ARCH" ;;
|
||||
esac
|
||||
step " Descargando Qdrant ${QDRANT_VERSION}..."
|
||||
curl -fsSL \
|
||||
"https://github.com/qdrant/qdrant/releases/download/${QDRANT_VERSION}/qdrant-${QDRANT_ARCH}.tar.gz" \
|
||||
-o /tmp/qdrant.tar.gz
|
||||
tar -C "$QDRANT_INSTALL_DIR" -xzf /tmp/qdrant.tar.gz
|
||||
chmod +x "$QDRANT_INSTALL_DIR/qdrant"
|
||||
rm /tmp/qdrant.tar.gz
|
||||
info "Qdrant ${QDRANT_VERSION} instalado en ${QDRANT_INSTALL_DIR}"
|
||||
else
|
||||
info "Qdrant ya instalado en ${QDRANT_INSTALL_DIR}"
|
||||
fi
|
||||
|
||||
# =============================================================================
|
||||
# 9. USUARIO DEL SISTEMA rss2
|
||||
# =============================================================================
|
||||
step "Creando usuario del sistema 'rss2'..."
|
||||
if ! id rss2 &>/dev/null; then
|
||||
useradd -r -m -d /opt/rss2 -s /bin/bash rss2
|
||||
info "Usuario 'rss2' creado"
|
||||
else
|
||||
info "Usuario 'rss2' ya existe"
|
||||
fi
|
||||
|
||||
# Crear estructura de directorios
|
||||
mkdir -p \
|
||||
/opt/rss2/bin \
|
||||
/opt/rss2/src \
|
||||
/opt/rss2/data/wiki_images \
|
||||
/opt/rss2/data/qdrant_storage \
|
||||
/opt/rss2/hf_cache \
|
||||
/opt/rss2/models \
|
||||
/opt/rss2/frontend/dist \
|
||||
/opt/rss2/logs \
|
||||
/opt/rss2/backups
|
||||
chown -R rss2:rss2 /opt/rss2
|
||||
info "Directorios /opt/rss2 creados"
|
||||
|
||||
# =============================================================================
|
||||
# 10. PYTHON VIRTUALENV + DEPENDENCIAS BASE
|
||||
# =============================================================================
|
||||
step "Creando virtualenv Python en /opt/rss2/venv..."
|
||||
if [[ ! -d /opt/rss2/venv ]]; then
|
||||
python3 -m venv /opt/rss2/venv
|
||||
fi
|
||||
/opt/rss2/venv/bin/pip install --upgrade pip setuptools wheel -q
|
||||
info "Virtualenv listo"
|
||||
|
||||
# Dependencias base (sin los modelos pesados de ML)
|
||||
step "Instalando dependencias Python base..."
|
||||
/opt/rss2/venv/bin/pip install -q \
|
||||
psycopg2-binary \
|
||||
langdetect \
|
||||
python-dotenv \
|
||||
requests \
|
||||
beautifulsoup4 \
|
||||
lxml \
|
||||
redis \
|
||||
qdrant-client \
|
||||
numpy \
|
||||
scikit-learn \
|
||||
tqdm
|
||||
info "Dependencias Python base instaladas"
|
||||
|
||||
# =============================================================================
|
||||
# 11. DEPENDENCIAS ML (pesadas - opcional en este paso)
|
||||
# =============================================================================
|
||||
echo ""
|
||||
echo -e "${YELLOW}[?]${NC} Instalar dependencias ML pesadas ahora?"
|
||||
echo " (ctranslate2, transformers, sentence-transformers, spaCy)"
|
||||
echo " Puede tardar 20-40 minutos y usar ~5 GB de disco."
|
||||
echo -n " [s/N]: "
|
||||
read -r install_ml
|
||||
|
||||
if [[ "${install_ml,,}" == "s" || "${install_ml,,}" == "si" || "${install_ml,,}" == "y" ]]; then
|
||||
step "Instalando dependencias ML (esto tarda)..."
|
||||
/opt/rss2/venv/bin/pip install -q \
|
||||
ctranslate2>=4.0.0 \
|
||||
transformers==4.43.3 \
|
||||
sentencepiece \
|
||||
sacremoses \
|
||||
accelerate \
|
||||
sentence-transformers==3.0.1 \
|
||||
"spacy>=3.7,<4.0" \
|
||||
torch --index-url https://download.pytorch.org/whl/cpu
|
||||
info "Dependencias ML instaladas"
|
||||
|
||||
step "Descargando modelo spaCy en español..."
|
||||
/opt/rss2/venv/bin/python -m spacy download es_core_news_lg
|
||||
info "Modelo spaCy es_core_news_lg listo"
|
||||
|
||||
step "Convirtiendo modelo NLLB-200 a CTranslate2..."
|
||||
warn "Esto puede tardar 10-30 minutos y requiere ~2 GB de RAM"
|
||||
mkdir -p /opt/rss2/models
|
||||
/opt/rss2/venv/bin/python - <<'EOF'
|
||||
import os, sys
|
||||
os.makedirs("/opt/rss2/models/nllb-ct2", exist_ok=True)
|
||||
os.environ["HF_HOME"] = "/opt/rss2/hf_cache"
|
||||
try:
|
||||
from ctranslate2.converters import OpusMTConverter
|
||||
converter = OpusMTConverter("facebook/nllb-200-distilled-600M")
|
||||
converter.convert("/opt/rss2/models/nllb-ct2", quantization="int8", force=True)
|
||||
print("[OK] Modelo NLLB-200 convertido en /opt/rss2/models/nllb-ct2")
|
||||
except Exception as e:
|
||||
print(f"[ERROR] {e}")
|
||||
print("Convierte manualmente despues con: deploy/debian/convert_model.sh")
|
||||
sys.exit(0)
|
||||
EOF
|
||||
chown -R rss2:rss2 /opt/rss2/models /opt/rss2/hf_cache
|
||||
else
|
||||
warn "ML omitido. Ejecuta 'deploy/debian/install.sh' para instalarlas junto con el resto."
|
||||
warn "Sin ML: la traduccion y los embeddings no funcionaran."
|
||||
fi
|
||||
|
||||
chown -R rss2:rss2 /opt/rss2
|
||||
|
||||
# =============================================================================
|
||||
# RESUMEN
|
||||
# =============================================================================
|
||||
echo ""
|
||||
echo "================================================="
|
||||
echo -e " ${GREEN}Prerequisites instalados correctamente${NC}"
|
||||
echo "================================================="
|
||||
echo ""
|
||||
echo " Sistema: $PRETTY_NAME"
|
||||
echo " Go: $(go version 2>/dev/null | awk '{print $3}')"
|
||||
echo " Python: $(python3 --version)"
|
||||
echo " Node.js: $(node --version)"
|
||||
echo " PostgreSQL: $(psql --version | awk '{print $3}')"
|
||||
echo " Redis: $(redis-server --version | awk '{print $3}' | tr -d ',')"
|
||||
echo " Nginx: $(nginx -v 2>&1 | cut -d'/' -f2)"
|
||||
echo ""
|
||||
echo " Siguiente paso:"
|
||||
echo " sudo bash deploy/debian/install.sh"
|
||||
echo ""
|
||||
Loading…
Add table
Add a link
Reference in a new issue