Остання активність 4 hours ago

atareao's Avatar atareao ревизій цього gist 4 hours ago. До ревизії

1 file changed, 386 insertions

init-lab.sh(файл створено)

@@ -0,0 +1,386 @@
1 + #!/bin/bash
2 + # =============================================================================
3 + # init-lab.sh — Inicialización del laboratorio de IA local
4 + # =============================================================================
5 + #
6 + # Uso:
7 + # chmod +x init-lab.sh
8 + # ./init-lab.sh
9 + #
10 + # Descripción:
11 + # Script de inicialización rápida del laboratorio. Crea la estructura de
12 + # directorios recomendada en el episodio, descarga los modelos esenciales
13 + # y genera un docker-compose.yml básico para empezar.
14 + #
15 + # Este script está diseñado para que el oyente pueda poner en marcha su
16 + # laboratorio con un solo comando después de instalar Ollama y Docker.
17 + #
18 + # Estructura que crea:
19 + # ~/lab-ia/
20 + # ├── docker/
21 + # │ ├── ollama/
22 + # │ ├── open-webui/
23 + # │ └── docker-compose.yml
24 + # ├── modelos/
25 + # ├── datos/
26 + # │ ├── notas/
27 + # │ ├── transcripciones/
28 + # │ └── embeddings/
29 + # ├── scripts/
30 + # └── config/
31 + # ├── ollama/
32 + # └── open-webui/
33 + #
34 + # Requisitos:
35 + # - Ollama instalado (ver 02-instalacion/setup-ollama.sh)
36 + # - Docker instalado (para el docker-compose.yml)
37 + # - Conexión a internet (para descargar modelos)
38 + # - ~5 GB de espacio libre
39 + #
40 + # =============================================================================
41 +
42 + set -euo pipefail
43 +
44 + # Colores
45 + VERDE='\033[0;32m'
46 + AMARILLO='\033[1;33m'
47 + AZUL='\033[0;34m'
48 + ROJO='\033[0;31m'
49 + RESET='\033[0m'
50 +
51 + # Directorio base del laboratorio
52 + LAB_DIR="$HOME/lab-ia"
53 +
54 + echo -e "${AZUL}╔══════════════════════════════════════════════════════╗${RESET}"
55 + echo -e "${AZUL}║ 🔬 Inicialización del Laboratorio de IA Local ║${RESET}"
56 + echo -e "${AZUL}║ Episodio 827 — Recursos IA: el botiquín del ║${RESET}"
57 + echo -e "${AZUL}║ explorador ║${RESET}"
58 + echo -e "${AZUL}╚══════════════════════════════════════════════════════╝${RESET}"
59 + echo ""
60 +
61 + # =============================================================================
62 + # PASO 1: Comprobar requisitos
63 + # =============================================================================
64 + echo -e "${AZUL}[1/5] Comprobando requisitos...${RESET}"
65 + echo ""
66 +
67 + REQUISITOS_OK=true
68 +
69 + # Ollama
70 + echo -n " Ollama: "
71 + if command -v ollama &>/dev/null; then
72 + echo -e "${VERDE}✓${RESET}"
73 + else
74 + echo -e "${ROJO}✗${RESET}"
75 + echo " → Instala Ollama primero: curl -fsSL https://ollama.com/install.sh | sh"
76 + REQUISITOS_OK=false
77 + fi
78 +
79 + # Docker
80 + echo -n " Docker: "
81 + if command -v docker &>/dev/null; then
82 + echo -e "${VERDE}✓${RESET}"
83 + else
84 + echo -e "${AMARILLO}⚠${RESET}"
85 + echo " → Docker no está instalado. El docker-compose.yml se creará igual."
86 + echo " → Instálalo con: curl -fsSL https://get.docker.com | sh"
87 + fi
88 +
89 + # Espacio en disco (~5 GB necesarios)
90 + echo -n " Espacio en disco: "
91 + ESPACIO_LIBRE=$(df -BG "$HOME" | tail -1 | awk '{print $4}' | sed 's/G//')
92 + if [ "$ESPACIO_LIBRE" -ge 10 ]; then
93 + echo -e "${VERDE}✓${RESET} ($ESPACIO_LIBRE GB libres)"
94 + elif [ "$ESPACIO_LIBRE" -ge 5 ]; then
95 + echo -e "${AMARILLO}⚠${RESET} ($ESPACIO_LIBRE GB libres — suficiente pero justo)"
96 + else
97 + echo -e "${ROJO}✗${RESET} ($ESPACIO_LIBRE GB libres — necesitas al menos 5 GB)"
98 + REQUISITOS_OK=false
99 + fi
100 +
101 + echo ""
102 +
103 + if [ "$REQUISITOS_OK" = false ]; then
104 + echo " ERROR: Requisitos insuficientes. Revisa los mensajes anteriores."
105 + exit 1
106 + fi
107 +
108 + # =============================================================================
109 + # PASO 2: Crear estructura de directorios
110 + # =============================================================================
111 + echo -e "${AZUL}[2/5] Creando estructura de directorios...${RESET}"
112 + echo ""
113 +
114 + mkdir -p "$LAB_DIR"
115 + mkdir -p "$LAB_DIR/docker/ollama"
116 + mkdir -p "$LAB_DIR/docker/open-webui"
117 + mkdir -p "$LAB_DIR/modelos"
118 + mkdir -p "$LAB_DIR/datos/notas"
119 + mkdir -p "$LAB_DIR/datos/transcripciones"
120 + mkdir -p "$LAB_DIR/datos/embeddings"
121 + mkdir -p "$LAB_DIR/scripts"
122 + mkdir -p "$LAB_DIR/config/ollama"
123 + mkdir -p "$LAB_DIR/config/open-webui"
124 +
125 + echo " Estructura creada en: ${AZUL}${LAB_DIR}${RESET}"
126 + echo ""
127 + echo " ${LAB_DIR}/"
128 + echo " ├── docker/"
129 + echo " │ ├── ollama/"
130 + echo " │ ├── open-webui/"
131 + echo " │ └── docker-compose.yml (se crea a continuación)"
132 + echo " ├── modelos/"
133 + echo " ├── datos/"
134 + echo " │ ├── notas/"
135 + echo " │ ├── transcripciones/"
136 + echo " │ └── embeddings/"
137 + echo " ├── scripts/"
138 + echo " └── config/"
139 + echo " ├── ollama/"
140 + echo " └── open-webui/"
141 + echo ""
142 +
143 + # =============================================================================
144 + # PASO 3: Crear docker-compose.yml básico
145 + # =============================================================================
146 + echo -e "${AZUL}[3/5] Creando docker-compose.yml básico...${RESET}"
147 + echo ""
148 +
149 + COMPOSE_FILE="$LAB_DIR/docker/docker-compose.yml"
150 +
151 + cat > "$COMPOSE_FILE" << 'COMPOSE_EOF'
152 + # =============================================================================
153 + # docker-compose.yml — Laboratorio IA Local
154 + # Generado por init-lab.sh del Episodio 827
155 + # =============================================================================
156 + #
157 + # Uso:
158 + # docker compose up -d # Levantar todos los servicios
159 + # docker compose down # Detener todos los servicios
160 + # docker compose logs -f # Ver logs en tiempo real
161 + #
162 + # Servicios:
163 + # - ollama: Gestor de modelos de lenguaje (API en :11434)
164 + # - open-webui: Interfaz gráfica web (web en :3000)
165 + #
166 + # Requisitos:
167 + # - Docker Engine 24+ o Podman 4+
168 + # - Docker Compose v2+
169 + #
170 + # =============================================================================
171 +
172 + services:
173 + # ---------------------------------------------------------------------------
174 + # Ollama — Gestor de modelos de lenguaje
175 + # ---------------------------------------------------------------------------
176 + ollama:
177 + image: ollama/ollama:latest
178 + container_name: ollama-server
179 + hostname: ollama
180 + volumes:
181 + # Persistencia de modelos descargados
182 + - ./ollama/models:/root/.ollama
183 + ports:
184 + # API REST de Ollama
185 + - "11434:11434"
186 + environment:
187 + # Mantener el modelo en memoria para respuestas más rápidas
188 + - OLLAMA_KEEP_ALIVE=5m
189 + # Número máximo de modelos cargados simultáneamente
190 + - OLLAMA_NUM_PARALLEL=1
191 + # Límite de contexto (ventana de tokens)
192 + - OLLAMA_CONTEXT_LENGTH=8192
193 + restart: unless-stopped
194 + healthcheck:
195 + test: ["CMD", "curl", "-f", "http://localhost:11434/api/tags"]
196 + interval: 30s
197 + timeout: 10s
198 + retries: 3
199 + start_period: 40s
200 + networks:
201 + - ia-local-net
202 +
203 + # ---------------------------------------------------------------------------
204 + # Open WebUI — Interfaz gráfica para chatear con modelos
205 + # ---------------------------------------------------------------------------
206 + open-webui:
207 + image: ghcr.io/open-webui/open-webui:main
208 + container_name: open-webui
209 + depends_on:
210 + ollama:
211 + condition: service_healthy
212 + volumes:
213 + # Persistencia de conversaciones, configuraciones, archivos subidos
214 + - ./open-webui/data:/app/backend/data
215 + ports:
216 + # Interfaz web
217 + - "3000:8080"
218 + environment:
219 + # URL del servicio Ollama (nombre del contenedor, no localhost)
220 + - OLLAMA_BASE_URL=http://ollama:11434
221 + # Tiempo máximo de espera para respuestas largas
222 + - WEBUI_TIMEOUT=300
223 + restart: unless-stopped
224 + healthcheck:
225 + test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
226 + interval: 30s
227 + timeout: 10s
228 + retries: 3
229 + start_period: 60s
230 + networks:
231 + - ia-local-net
232 +
233 + # ---------------------------------------------------------------------------
234 + # Redes
235 + # ---------------------------------------------------------------------------
236 + networks:
237 + ia-local-net:
238 + name: ia-local-network
239 + driver: bridge
240 + COMPOSE_EOF
241 +
242 + echo -e " ${VERDE}✓${RESET} docker-compose.yml creado en:"
243 + echo " $COMPOSE_FILE"
244 + echo ""
245 +
246 + # =============================================================================
247 + # PASO 4: Descargar modelos esenciales
248 + # =============================================================================
249 + echo -e "${AZUL}[4/5] Descargando modelos esenciales...${RESET}"
250 + echo ""
251 +
252 + # Modelo de lenguaje pequeño (ideal para empezar)
253 + MODELO_LENGUAJE="qwen2.5:3b"
254 + echo " Modelo de lenguaje: ${AMARILLO}${MODELO_LENGUAJE}${RESET}"
255 + echo " (~2 GB — recomendado para empezar)"
256 + echo ""
257 +
258 + if ollama list 2>/dev/null | grep -q "^${MODELO_LENGUAJE}\s"; then
259 + echo -e " ${VERDE}✓${RESET} ${MODELO_LENGUAJE} ya está descargado."
260 + else
261 + echo " Descargando ${MODELO_LENGUAJE}..."
262 + echo " (Esto puede tardar según tu conexión)"
263 + ollama pull "$MODELO_LENGUAJE"
264 + echo -e " ${VERDE}✓${RESET} ${MODELO_LENGUAJE} descargado."
265 + fi
266 + echo ""
267 +
268 + # Modelo de embeddings (para RAG y búsqueda semántica)
269 + MODELO_EMBED="nomic-embed-text"
270 + echo " Modelo de embeddings: ${AMARILLO}${MODELO_EMBED}${RESET}"
271 + echo " (~0.3 GB — necesario para RAG y búsqueda semántica)"
272 + echo ""
273 +
274 + if ollama list 2>/dev/null | grep -q "^${MODELO_EMBED}\s"; then
275 + echo -e " ${VERDE}✓${RESET} ${MODELO_EMBED} ya está descargado."
276 + else
277 + echo " Descargando ${MODELO_EMBED}..."
278 + ollama pull "$MODELO_EMBED"
279 + echo -e " ${VERDE}✓${RESET} ${MODELO_EMBED} descargado."
280 + fi
281 + echo ""
282 +
283 + # =============================================================================
284 + # PASO 5: Crear script de respaldo básico
285 + # =============================================================================
286 + echo -e "${AZUL}[5/5] Creando script de respaldo básico...${RESET}"
287 + echo ""
288 +
289 + BACKUP_SCRIPT="$LAB_DIR/scripts/backup.sh"
290 +
291 + cat > "$BACKUP_SCRIPT" << 'BACKUP_EOF'
292 + #!/bin/bash
293 + # backup.sh — Respaldo del laboratorio de IA local
294 + #
295 + # Uso:
296 + # ./backup.sh # Respaldo completo
297 + # ./backup.sh --modelos # Solo respaldo de modelos
298 + # ./backup.sh --datos # Solo respaldo de datos
299 + #
300 + # Descripción:
301 + # Crea una copia de seguridad de los elementos esenciales del laboratorio:
302 + # modelos descargados, configuraciones y datos generados.
303 +
304 + set -euo pipefail
305 +
306 + BACKUP_DIR="$HOME/lab-ia-backup-$(date +%Y%m%d)"
307 + LAB_DIR="$HOME/lab-ia"
308 +
309 + echo "=============================================="
310 + echo " Respaldo del Laboratorio IA Local"
311 + echo "=============================================="
312 + echo ""
313 + echo " Directorio de respaldo: $BACKUP_DIR"
314 + echo ""
315 +
316 + mkdir -p "$BACKUP_DIR"
317 +
318 + # Respaldar configuración de Ollama
319 + if [ -d "$HOME/.ollama" ]; then
320 + echo " Respaldando modelos de Ollama..."
321 + cp -r "$HOME/.ollama" "$BACKUP_DIR/ollama"
322 + echo " ✓ Modelos respaldados"
323 + fi
324 +
325 + # Respaldar docker-compose y configuraciones
326 + if [ -d "$LAB_DIR/docker" ]; then
327 + echo " Respaldando docker-compose..."
328 + cp -r "$LAB_DIR/docker" "$BACKUP_DIR/docker"
329 + echo " ✓ Configuración Docker respaldada"
330 + fi
331 +
332 + # Respaldar scripts personalizados
333 + if [ -d "$LAB_DIR/scripts" ]; then
334 + echo " Respaldando scripts..."
335 + cp -r "$LAB_DIR/scripts" "$BACKUP_DIR/scripts"
336 + echo " ✓ Scripts respaldados"
337 + fi
338 +
339 + echo ""
340 + echo " Respaldo completado en: $BACKUP_DIR"
341 + echo " Para restaurar: cp -r $BACKUP_DIR/* $HOME/"
342 + echo "=============================================="
343 + BACKUP_EOF
344 +
345 + chmod +x "$BACKUP_SCRIPT"
346 +
347 + echo -e " ${VERDE}✓${RESET} Script de respaldo creado: $BACKUP_SCRIPT"
348 + echo ""
349 +
350 + # =============================================================================
351 + # CIERRE
352 + # =============================================================================
353 + echo -e "${VERDE}╔══════════════════════════════════════════════════════╗${RESET}"
354 + echo -e "${VERDE}║ ✅ Laboratorio inicializado con éxito ║${RESET}"
355 + echo -e "${VERDE}╚══════════════════════════════════════════════════════╝${RESET}"
356 + echo ""
357 + echo " Tu laboratorio está listo en: ${AZUL}${LAB_DIR}${RESET}"
358 + echo ""
359 + echo " Modelos descargados:"
360 + ollama list 2>/dev/null | tail -n +2 | while read -r line; do
361 + echo " • $line"
362 + done
363 + echo ""
364 + echo " Para empezar a usar tu laboratorio:"
365 + echo ""
366 + echo " 1. Abre la interfaz web (si tienes Docker):"
367 + echo " cd ${LAB_DIR}/docker"
368 + echo " docker compose up -d"
369 + echo " → http://localhost:3000"
370 + echo ""
371 + echo " 2. Chatea desde terminal:"
372 + echo " ollama run qwen2.5:3b \"¿Qué puedo hacer con IA local?\""
373 + echo ""
374 + echo " 3. Prueba la API REST:"
375 + echo " curl http://localhost:11434/api/tags"
376 + echo ""
377 + echo " 4. Haz un respaldo:"
378 + echo " ${LAB_DIR}/scripts/backup.sh"
379 + echo ""
380 + echo " 📖 Guía completa en: atareao.es/827"
381 + echo ""
382 + echo " Próximo episodio (829): Skills imprescindibles para tu agente IA"
383 + echo " Vamos a enseñar al modelo a usar herramientas."
384 + echo ""
385 + echo " Nos oímos el jueves. Sed felices. Y seguid trasteando."
386 + echo ""
Новіше Пізніше