#!/usr/bin/env bash # d0a1 quickstart deployment script # Sube Ollama + Open WebUI en Docker. Lee configuracion de .env. set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" cd "$SCRIPT_DIR" # --- Color helpers ----------------------------------------------------------- if [ -t 1 ]; then BOLD="\033[1m"; GREEN="\033[32m"; YELLOW="\033[33m"; RED="\033[31m"; RESET="\033[0m" else BOLD=""; GREEN=""; YELLOW=""; RED=""; RESET="" fi info() { printf "%b\n" "${BOLD}${GREEN}>>>${RESET} $*"; } warn() { printf "%b\n" "${BOLD}${YELLOW}>>>${RESET} $*"; } err() { printf "%b\n" "${BOLD}${RED}>>>${RESET} $*" >&2; } # --- Pre-flight checks ------------------------------------------------------- if ! command -v docker >/dev/null 2>&1; then err "Docker no esta instalado. Instala Docker Desktop o docker-ce." err "https://docs.docker.com/get-docker/" exit 1 fi if ! docker info >/dev/null 2>&1; then err "Docker daemon no responde. Inicia Docker Desktop o el servicio." exit 1 fi if ! docker compose version >/dev/null 2>&1; then err "Docker Compose v2 no esta disponible. Actualiza Docker." exit 1 fi # --- Config ------------------------------------------------------------------ if [ ! -f .env ]; then warn "No existe .env, copiando .env.example" cp .env.example .env info "Edita .env si quieres cambiar puertos o el modelo por defecto." fi # Carga .env sin requerir bash 4+ (compatible con macOS) set -a # shellcheck disable=SC1091 . ./.env set +a WEBUI_PORT="${WEBUI_PORT:-3000}" DEFAULT_MODEL="${DEFAULT_MODEL:-llama3.2:3b}" # --- Memoria del sistema (Linux + macOS) ------------------------------------- total_ram_gb() { case "$(uname -s)" in Linux) awk '/MemTotal/ {printf "%d\n", $2/1024/1024}' /proc/meminfo ;; Darwin) sysctl -n hw.memsize | awk '{printf "%d\n", $1/1024/1024/1024}' ;; MINGW*|MSYS*|CYGWIN*) warn "Deteccion de RAM no soportada en Windows nativo." warn "Usa WSL2 o asume 8 GB como baseline seguro." echo "0" ;; *) echo "0" ;; esac } RAM_GB=$(total_ram_gb) # --- Arranque ---------------------------------------------------------------- info "Levantando servicios (esto puede tardar unos segundos)..." docker compose up -d info "Esperando a que Ollama este listo..." TIMEOUT=60 ELAPSED=0 until docker exec d0a1-ollama ollama list >/dev/null 2>&1; do sleep 2 ELAPSED=$((ELAPSED + 2)) if [ "$ELAPSED" -ge "$TIMEOUT" ]; then err "Ollama no arranco en ${TIMEOUT}s. Revisa 'docker compose logs ollama'." exit 1 fi done # grep -qF hace match literal (sin regex), evitando que un punto en el # nombre del modelo (p.ej. qwen2.5:7b) actue como wildcard. # --- Modelo por defecto ------------------------------------------------------ if ! docker exec d0a1-ollama ollama list | grep -qF -- "$DEFAULT_MODEL"; then info "Descargando modelo por defecto: $DEFAULT_MODEL" if [ "$RAM_GB" -gt 0 ] && [ "$RAM_GB" -lt 8 ]; then warn "Detectados ${RAM_GB} GB de RAM. Para este modelo se recomiendan 8 GB." warn "Si falla la carga, prueba con 'docker exec d0a1-ollama ollama pull llama3.2:1b'." fi docker exec d0a1-ollama ollama pull "$DEFAULT_MODEL" else info "Modelo $DEFAULT_MODEL ya esta descargado." fi # --- Resultado --------------------------------------------------------------- printf "\n" info "d0a1 quickstart listo!" printf "\n" printf " %bOpen WebUI:%b http://localhost:%s\n" "$BOLD" "$RESET" "$WEBUI_PORT" printf " %bOllama:%b http://localhost:%s\n" "$BOLD" "$RESET" "${OLLAMA_PORT:-11434}" printf "\n" info "Comandos utiles:" printf " docker compose logs -f # logs en tiempo real\n" printf " docker compose down # parar todo\n" printf " docker exec d0a1-ollama ollama pull # anadir modelos\n" printf "\n"