poc/poc.sh: - Verificacion de versiones: Go >=1.22, Node.js >=18 con mensaje de fix exacto - Deteccion de puertos en uso antes de arrancar (API, frontend, Redis) con instruccion de quien ocupa el puerto - show_log_tail(): muestra solo las lineas relevantes del log al fallar - Compilacion Go: filtra lineas de error reales (error:/undefined:) en vez de volcar todo el log - Backend no responde: sugiere probar DB y Redis individualmente con el comando exacto para diagnosticar - Frontend: distingue error de npm install vs error de build TypeScript - Flag --clean para borrar BD POC y empezar de cero - Logs separados por componente en /tmp/coconews-poc/logs/ deploy/debian/check.sh (nuevo): - Diagnostico completo del sistema post-instalacion - Verifica 16 servicios systemd con estado y fix especifico por cada uno - Prueba conectividad real: PostgreSQL, Redis (con auth), Qdrant HTTP, API Go, nginx - Muestra metricas de BD: total noticias, traducciones hechas y pendientes - Verifica binarios Go compilados y su tamano - Verifica modelos ML: NLLB-200, spaCy es_core_news_lg, sentence-transformers, ctranslate2 - Comprueba disco (avisa si >75% o >90%), permisos de /opt/rss2 y .env - Detecta si .env tiene valores por defecto sin cambiar - Modo --quick para ver solo estado arriba/abajo rapidamente - Resumen final con conteo de errores y advertencias, exit code 1 si hay errores deploy/debian/prerequisites.sh: - Comprobacion de espacio libre en disco al inicio (avisa si <10 GB) - apt-get update con log de error y sugerencias de fix - Seccion de troubleshooting en el resumen final con fixes comunes Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
327 lines
12 KiB
Bash
Executable file
327 lines
12 KiB
Bash
Executable file
#!/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
|
|
# =============================================================================
|
|
# Comprobar espacio en disco (mínimo 10 GB libres)
|
|
DISK_FREE_GB=$(df / --output=avail -BG | tail -1 | tr -d 'G ')
|
|
if [[ "${DISK_FREE_GB:-0}" -lt 10 ]]; then
|
|
warn "Espacio libre en disco: ${DISK_FREE_GB} GB (recomendado mínimo 10 GB)"
|
|
warn "Los modelos ML necesitan ~5 GB. Continua bajo tu responsabilidad."
|
|
fi
|
|
|
|
step "Actualizando repositorios apt..."
|
|
apt-get update -qq 2>/tmp/apt-update.log || {
|
|
echo -e "${RED}Error al actualizar repositorios apt.${NC}"
|
|
echo " Posibles causas:"
|
|
echo " • Sin conexión a internet"
|
|
echo " • Repositorios con errores: cat /tmp/apt-update.log"
|
|
echo " • Solución: apt-get update --fix-missing"
|
|
exit 1
|
|
}
|
|
|
|
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 Y SIGUIENTES PASOS
|
|
# =============================================================================
|
|
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 ""
|
|
echo " Si algo falló durante la instalación:"
|
|
echo " • apt falla: apt-get update --fix-missing"
|
|
echo " • Go no descarga: verifica conectividad → curl https://go.dev"
|
|
echo " • Qdrant no baja: descárgalo manualmente en"
|
|
echo " https://github.com/qdrant/qdrant/releases"
|
|
echo " • pip falla: python3 -m venv /opt/rss2/venv --clear"
|
|
echo " • Diagnóstico: bash deploy/debian/check.sh"
|
|
echo ""
|