#!/bin/bash # ────────────────────────────────────────────── # d0a1 pack — Open WebUI # Chat con IA en tu navegador. Como ChatGPT, pero privado. # ────────────────────────────────────────────── # Local: ./deploy.sh local → http://localhost:3000 # VPS: ./deploy.sh vps → http://TU_IP:3000 # Stop: ./deploy.sh stop # ────────────────────────────────────────────── set -e GREEN='\033[0;32m' CYAN='\033[0;36m' YELLOW='\033[0;33m' RED='\033[0;31m' BOLD='\033[1m' NC='\033[0m' MODE="${1:-local}" SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" COMPOSE_FILE="$SCRIPT_DIR/docker-compose.yml" echo "" echo -e "${BOLD}${CYAN}╔══════════════════════════════════════════╗${NC}" echo -e "${BOLD}${CYAN}║ d0a1 pack — Open WebUI ║${NC}" echo -e "${BOLD}${CYAN}║ Chat con IA. Privado. Sin cuotas. ║${NC}" echo -e "${BOLD}${CYAN}╚══════════════════════════════════════════╝${NC}" echo "" # ── Stop mode ─────────────────────────────── if [ "$MODE" = "stop" ]; then echo -e "${YELLOW}Parando...${NC}" docker compose -f "$COMPOSE_FILE" down echo -e "${GREEN}✓ Parado.${NC}" exit 0 fi # ── Check Docker ──────────────────────────── if ! command -v docker &>/dev/null; then echo -e "${RED}✗ Docker no está instalado.${NC}" echo "" echo "Instálalo: curl -fsSL https://get.docker.com | sh" exit 1 fi if ! docker compose version &>/dev/null; then echo -e "${RED}✗ Docker Compose v2 no disponible.${NC}" exit 1 fi echo -e "${GREEN}✓${NC} Docker: $(docker compose version --short 2>/dev/null || echo 'OK')" # ── Check RAM ─────────────────────────────── TOTAL_RAM_KB=$(grep MemTotal /proc/meminfo 2>/dev/null | awk '{print $2}' || echo "0") TOTAL_RAM_GB=$((TOTAL_RAM_KB / 1024 / 1024)) if [ "$TOTAL_RAM_GB" -lt 3 ]; then echo -e "${RED}✗ Se necesitan 4 GB de RAM mínimo (detectado: ${TOTAL_RAM_GB} GB).${NC}" exit 1 fi echo -e "${GREEN}✓${NC} RAM: ${TOTAL_RAM_GB} GB" # ── Mode info ─────────────────────────────── if [ "$MODE" = "local" ]; then echo -e "${YELLOW}Modo:${NC} local (tu ordenador)" echo -e " URL: ${CYAN}http://localhost:3000${NC}" elif [ "$MODE" = "vps" ]; then echo -e "${YELLOW}Modo:${NC} VPS (accesible desde fuera)" echo -e " URL: ${CYAN}http://$(hostname -I 2>/dev/null | awk '{print $1}' || echo 'TU_IP'):3000${NC}" echo "" echo -e " ${BOLD}¿No tienes VPS?${NC} Consigue uno con descuento:" echo -e " ${CYAN}https://d0a1.es/go/hetzner/${NC} — Hetzner Cloud" echo -e " ${CYAN}https://d0a1.es/go/contabo/${NC} — Contabo" else echo -e "${RED}Modo desconocido: $MODE${NC}" echo "Usa: ./deploy.sh local | vps | stop" exit 1 fi echo "" # ── Deploy ────────────────────────────────── echo -e "${YELLOW}Descargando contenedores (2-3 min la primera vez)...${NC}" docker compose -f "$COMPOSE_FILE" up -d # ── Pull model ─────────────────────────────── echo -e "${YELLOW}Descargando modelo de IA (llama3.2:3b, ~2 GB)...${NC}" MAX_WAIT=60 WAITED=0 until docker exec d0a1-ollama ollama ps &>/dev/null; do sleep 2 WAITED=$((WAITED + 2)) if [ "$WAITED" -ge "$MAX_WAIT" ]; then echo -e "${RED}✗ Ollama no arrancó. Revisa: docker logs d0a1-ollama${NC}" exit 1 fi done docker exec d0a1-ollama ollama pull llama3.2:3b # ── Done ──────────────────────────────────── echo "" echo -e "${BOLD}${GREEN}¡Listo! Tu IA está corriendo.${NC}" echo "" if [ "$MODE" = "local" ]; then echo -e " ${BOLD}Abre:${NC} ${CYAN}http://localhost:3000${NC}" else echo -e " ${BOLD}Abre:${NC} ${CYAN}http://$(hostname -I 2>/dev/null | awk '{print $1}' || echo 'TU_IP'):3000${NC}" fi echo "" echo -e " ${BOLD}Modelos alternativos:${NC}" echo " docker exec d0a1-ollama ollama pull qwen2.5:7b # Mejor en español" echo " docker exec d0a1-ollama ollama pull llama3.1:8b # Más calidad" echo "" echo -e " ${BOLD}Parar:${NC} ./deploy.sh stop" echo -e " ${BOLD}¿Quieres más?${NC} ${CYAN}https://d0a1.es/precios/${NC}" echo ""