viernes, 6 de marzo de 2026

Inteligencia Artificial "Low-Cost": Mi Clúster de Inferencia con iGPUs y Vulkan


Inteligencia Artificial "Low-Cost": Mi Clúster de Inferencia con iGPUs y Vulkan

¡Buenas, buenas! Después de una rodadita matutina por las trochas de Pance para despejar la mente y sentir el aire fresco, me quedé pensando en cómo el hardware que a veces subestimamos puede darnos sorpresas increíbles. Hoy no les vengo a hablar de GPUs de miles de dólares que consumen lo mismo que una soldadora eléctrica, ni de granjas de servidores ruidosas que parecen un avión despegando en la sala. Les traigo una historia de aprovechamiento máximo: cómo convertí un puñado de Mini PCs y una laptop veterana en un Clúster de Inferencia de IA plenamente funcional.

Ya dejando a lado tanta cháchara, vamos a lo que nos interesa. La meta era ambiciosa pero clara: correr modelos de lenguaje (LLMs) modernos como Llama 3.1 o Gemma 2 de forma 100% local y privada. El reto no era solo "correrlos", sino hacerlo aprovechando la aceleración por hardware de las gráficas integradas (iGPU) de Intel mediante el backend de Vulkan. Esto demuestra que no siempre necesitas una tarjeta dedicada para tener una experiencia digna; a veces, solo necesitas saberle hablar al silicio que ya tienes.



La Arquitectura: Un "Sancocho" de Nodos con Propósito

Para este proyecto, bautizado en mi inventario como el clúster Vulkan Multi-Nodo, utilicé Proxmox como orquestador base. La clave aquí fue la eficiencia extrema. En lugar de máquinas virtuales pesadas que reservan recursos y desperdician ciclos de reloj, opté por contenedores LXC con Debian 13 (Trixie). Esto reduce el overhead al mínimo, permitiendo que casi la totalidad de la RAM se dedique a cargar los tensores del modelo.

Aquí les presento a los integrantes de este equipo, cada uno con su "personalidad" y rol técnico definido:

  1. Seti (El Líder): Un GMKtec NucBox G3 Plus con el procesador Intel N150. Es la "joya de la corona" gracias a su arquitectura Alder Lake-N. Lo que lo hace especial es que le instalé los drivers Mesa v25.0.7, que manejan Vulkan de forma mucho más madura que las versiones estables de Debian. Es el nodo que rompió todos mis récords internos.

  2. Aurora & Cosmos: Dos guerreros representados por un Beelink MINI S y un S12 (N150 y N100 respectivamente). Estos son el motor constante del clúster. Aunque son procesadores de apenas 6 vatios, su soporte nativo para instrucciones VNNI (Vector Neural Network Instructions) los hace volar en tareas de cuantización, que es básicamente cómo comprimimos los modelos para que quepan en estas cajitas de fósforos.

  3. Yoga (La Veterana): Mi fiel Lenovo Yoga 720 (i7-8550U) heredada de cuando estuve trabajando en NetMidas. Aunque su iGPU UHD 620 ya muestra los años (Año 2018 aprox.) y su arquitectura Coffee Lake se siente cansada frente a los nuevos, la incluí como "línea base". Es fundamental tener un punto de comparación para entender qué tanto hemos avanzado en eficiencia en estos últimos cinco años.

  4. Gateway: Un contenedor Alpine Linux ultra-ligero con Nginx. Su trabajo es ser el "cerebro" que decide a qué nodo enviarle cada petición, actuando como un balanceador de carga de Capa 7 que entiende de tiempos de espera y estados de salud.


El Corazón Técnico: Llama.cpp + Vulkan

La magia no ocurre por arte de obra y gracia de cristo. El motor es llama.cpp, pero compilado específicamente desde la fuente para habilitar el backend de Vulkan (GGML_VULKAN=1). Esto es vital: si usas la versión estándar que viene en muchos instaladores "un solo clic", el proceso recae por defecto en el CPU y la velocidad cae al piso, convirtiendo la charla con la IA en un proceso agónico de un token por minuto.

El Desafío del Passthrough en LXC

Para que los contenedores LXC "vieran" el hardware gráfico, tuve que realizar un passthrough manual de los dispositivos de renderizado. En Proxmox, esto no es solo marcar una casilla en la interfaz gráfica. Hay que editar el archivo de configuración del contenedor (ej. /etc/pve/lxc/100.conf) y añadir las líneas mágicas que permiten el acceso a /dev/dri/renderD128.

Un detalle que me sacó canas y lágrimas: hay que asegurarse de que el GID (Group ID) del grupo render en el host de Proxmox coincida con el del contenedor Debian. Si no, tendrás errores de "Permission Denied" y la iGPU se quedará ahí, mirando sin hacer nada.


Script de Despliegue Parametrizado (llm-server.sh)

Usamos el flag --ngl 99 para indicarle a llama.cpp que intente meter todas las capas del modelo en la memoria de la GPU (VRAM compartida).

#!/bin/bash

################################################################################
# CONTRATO DE EJECUCION - LLAMA.CPP SERVER
#
# DESCRIPCION:
#   Levanta una instancia de llama-server optimizada para iGPU Intel (Vulkan).
#   Detecta automaticamente los hilos fisicos del nodo y aplica offloading
#   total a la GPU para maximizar t/s.
#
# PARAMETROS:
#   -m (Obligatorio) : Nombre del archivo .gguf (debe estar en /root/llama.cpp/models)
#   -p (Opcional)    : Puerto de escucha. Por defecto: 8080
#   -c (Opcional)    : Tamanio del contexto (KV Cache). Por defecto: 4096
#
# FORMA DE EJECUCION:
#   chmod +x llm-server.sh
#   ./llm-server.sh -m llama-3.1-8b.gguf
#   ./llm-server.sh -m gemma-2-2b.gguf -p 8081 -c 2048
#
################################################################################

# --- CONFIGURACION INTERNA ---
LLAMA_BASE_DIR="/root/llama.cpp"
MODEL_DIR="$LLAMA_BASE_DIR/models"
BINARY_PATH="$LLAMA_BASE_DIR/build/bin/llama-server"
DEFAULT_CTX=4096
DEFAULT_PORT=8080
LOG_FILE="$LLAMA_BASE_DIR/llama_server.log"

usage() {
    echo "❌ Error de sintaxis."
    echo "Uso: $0 -m <modelo.gguf> [-p <puerto>] [-c <contexto>]"
    exit 1
}

# --- PARSEO DE ARGUMENTOS ---
while getopts "m:p:c:" opt; do
    case $opt in
        m) MODEL_FILE=$OPTARG ;;
        p) PORT=$OPTARG ;;
        c) CTX=$OPTARG ;;
        *) usage ;;
    esac
done

if [ -z "$MODEL_FILE" ]; then usage; fi

FINAL_PORT=${PORT:-$DEFAULT_PORT}
FINAL_CTX=${CTX:-$DEFAULT_CTX}
MODEL_PATH="$MODEL_DIR/$MODEL_FILE"

# Verificacion de existencia del binario y modelo
if [ ! -f "$BINARY_PATH" ]; then
    echo "❌ Error: No se encuentra el binario en $BINARY_PATH"
    exit 1
fi

if [ ! -f "$MODEL_PATH" ]; then
    echo "❌ Error: El modelo $MODEL_FILE no existe en $MODEL_DIR"
    exit 1
fi

# Deteccion de hilos fisicos (Optimizando para Alder Lake-N / Coffee Lake)
THREADS=$(lscpu | grep "^Core(s) per socket:" | awk '{print $4}')

echo "--------------------------------------------------------"
echo "🖥️  NODE: $(hostname) | 📍 EXEC FROM: $(pwd)"
echo "🚀 INICIANDO: $MODEL_FILE"
echo "📡 PUERTO: $FINAL_PORT | 🧠 CTX: $FINAL_CTX | 🧵 THREADS: $THREADS"
echo "📄 LOG FILE: $LOG_FILE"
echo "--------------------------------------------------------"

# --- EJECUCION ---
# Cambiamos al directorio base para que los recursos relativos del binario funcionen
cd "$LLAMA_BASE_DIR" || exit

# Ejecucion del servidor LLM Llama.cpp
./build/bin/llama-server \
    -m "$MODEL_PATH" \
    --host 0.0.0.0 \
    --port "$FINAL_PORT" \
    --ctx-size "$FINAL_CTX" \
    --n-gpu-layers 99 \
    --flash-attn on \
    --threads "$THREADS" \
    --cont-batching \
    --parallel 2 \
    --slots \
    2>&1 | tee "$LOG_FILE"


Configuración del Servicio (Systemd) para Disponibilidad 24/7

Para que el sistema sea robusto, configuré cada nodo para que el servidor de inferencia se levante automáticamente.

[Unit]
Description=Llama.cpp API Server (Cluster Node)
After=network.target

[Service]
Type=simple
User=root
WorkingDirectory=/root/llama.cpp
# Parametros: -m modelo, -p puerto (opcional), -c contexto (opcional)
ExecStart=/root/llm-server.sh -m gemma-2-2b-q8_0.gguf
Restart=always
RestartSec=5
StandardOutput=append:/root/llama.cpp/llama_server.log
StandardError=inherit
# Acceso a Librerias y Dispositivos iGPU
Environment=LD_LIBRARY_PATH=/usr/local/lib
Environment=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
DeviceAllow=/dev/dri/renderD128 rw
DeviceAllow=/dev/dri/card0 rw

[Install]
WantedBy=multi-user.target


El Balanceador: Nginx como Director de Orquesta

Aquí es donde el "sancocho" se vuelve un clúster de verdad. El Gateway centraliza las peticiones. Si Seti está procesando una consulta larga (como resumir un PDF de 50 páginas), Nginx detecta que el nodo está ocupado y redirige la siguiente pregunta a Aurora o Cosmos.

Implementé una configuración de backup inteligente. La Yoga, al ser la más lenta y ruidosa con sus ventiladores, solo entra en acción si los tres Mini PCs están saturados. Es como tener un ciclista veterano en el equipo: solo lo llamas cuando el terreno se pone realmente feo y necesitas todas las piernas disponibles.

# Configuracion del Cluster de Inferencia LLM
upstream llm_backend {
    # 'least_conn' es critico dado que tienes hardware heterogeneo (Yoga vs Seti)
    least_conn;

    server 10.10.1.51:8080; # Yoga
    server 10.10.1.52:8080; # Aurora
    server 10.10.1.53:8080; # Cosmos
    server 10.10.1.54:8080; # Seti

    # Mantiene hasta 32 conexiones abiertas con los backends para reducir latencia
    keepalive 32;
}

server {
    listen 80;
    server_name _; # Responde a cualquier IP que llegue al contenedor

    # Tamanio maximo de prompt/archivo (64MB es seguro para la mayoria de casos)
    client_max_body_size 64M;

    location / {
        proxy_pass http://llm_backend;
        
        # Cabeceras estandar de Proxy
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # CONFIGURACION PARA LLM STREAMING (CRITICO)
        # Esto permite que los tokens aparezcan uno a uno en la UI
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_cache off;
        proxy_buffering off;
        #proxy_chunked_transfer_encoding on;
        
        # Tiempos de espera (Inferencia puede tardar en modelos grandes)
        proxy_read_timeout 600s;
        proxy_send_timeout 600s;

        # Desactivar compresion para evitar retrasos en el flujo de tokens
        gzip off;
    }
}


Resultados y Conclusiones: La Realidad del Silicio

Después de varias semanas de pruebas intensas, comparando logs mientras me tomaba un tinto cargado, estas son las conclusiones más valiosas para cualquier entusiasta del HomeLab y Self-Hosting:




  • La importancia crítica de los drivers: No me cansaré de decirlo. El nodo Seti logró un pico de 30.9 tokens/s en la fase de "prefill" (cuando la IA lee y procesa tu pregunta) con el modelo Gemma-2 2B. Esto es una bestialidad. Comparado con los ~4.5 t/s de la Yoga, hablamos de una eficiencia casi 7 veces superior en un chip que consume menos que una bombilla LED. Los drivers Mesa v25 son, sin duda, el ingrediente secreto.





  • El Cuello de Botella de la RAM (Single Channel): Aquí está la cruda realidad que no te cuentan en los folletos, DDR4 @ 3200MHz. Al ser Mini PCs económicas con memoria de un solo canal, el bus de datos se satura rápidamente. Aunque la iGPU Xe sea potente, la velocidad de generación final (cuando la IA ya te está respondiendo) se estanca en unos ~2.5 t/s para modelos de 8B. No es para escribir una novela en cinco segundos, pero para un chat de soporte técnico o resúmenes, va sobrado.




  • VNNI y el Salto Generacional: La arquitectura Alder Lake-N marca un hito. Estas instrucciones dedicadas para redes neuronales permiten que estos procesadores "baratos" superen a procesadores i7 de generaciones anteriores que costaban el triple. Es la democratización de la inferencia.


Finalmente, integré todo con Open WebUI corriendo en Docker. Es la "cara bonita" del proyecto, con una interfaz impecable que se conecta al Gateway de Nginx y me permite elegir modelos o crear documentos colaborativos con la IA. Todo esto con la tranquilidad de que mis datos no están alimentando a ninguna corporación; se quedan en mi red, protegidos por mis propios túneles y mi firewall.




Espero que este recorrido por las entrañas de mi infraestructura les sirva de inspiración. A veces la solución no es comprar hardware a escala empresarial o de segunda mano que calienta toda la casa, sino entender cómo hacer que lo pequeño y moderno trabaje en equipo.


Un bit más en la web.


martes, 10 de febrero de 2026

Habilidades 2030: ¿Cómo prepararnos para convivir con la IA?

En esta entrada quiero compartir un análisis sobre las competencias que, según el World Economic Forum (Foro Económico Mundial, una organización internacional que analiza las tendencias globales), serán esenciales para nosotros los humanos de aquí al año 2030.

Con la rápida adopción de la IA (Inteligencia Artificial, que es la simulación de procesos de inteligencia humana por parte de máquinas), el panorama laboral está cambiando. Así como en entradas anteriores les he explicado cómo configurar un servidor o qué es un algoritmo, hoy quiero explicarles qué habilidades debemos "instalar" en nosotros mismos para no quedar obsoletos.


Humano 2030

Las he dividido en dos categorías principales:

1. Habilidades Blandas (Soft Skills)

Estas son habilidades interpersonales y de pensamiento que definen cómo trabajamos y nos relacionamos.

  • Pensamiento Analítico: Es la capacidad de desglosar problemas complejos en partes más pequeñas para entenderlos y resolverlos. La IA puede darnos datos, pero nosotros debemos analizarlos.
  • Resiliencia y Flexibilidad: Se refiere a la capacidad de recuperarse de situaciones difíciles y adaptarse a los cambios. En tecnología, esto es vital porque las herramientas cambian cada mes.
  • Alfabetización Tecnológica: No solo es saber usar una computadora, es entender cómo funcionan las nuevas herramientas para sacarles provecho.

2. Habilidades Duras (Hard Skills)

Son conocimientos técnicos específicos que se adquieren mediante la formación o la práctica constante.

  • IA y Big Data: El Big Data (Grandes volúmenes de datos que superan la capacidad del software convencional para ser procesados) es el combustible de la IA. Aprender a gestionar estos datos será fundamental.
  • Habilidades Verdes (Green Skills): Son los conocimientos necesarios para adaptar los procesos industriales y digitales hacia la sostenibilidad y el cuidado del medio ambiente.
  • Ciberseguridad: Con más procesos automatizados, la protección de la información se vuelve una prioridad técnica de primer nivel.

¿Por qué es importante esto hoy?

Esto lo escribo porque, al igual que cuando configuramos un servidor FTP (File Transfer Protocol, un protocolo para transferir archivos entre sistemas conectados a una red TCP), si no tenemos los parámetros correctos, el sistema simplemente no funciona.

Para el 2030, el desafío no es que la IA nos reemplace, sino que sepamos ser los "arquitectos" que diseñan las instrucciones. La IA es excelente siguiendo reglas (como un algoritmo), pero los humanos somos los únicos capaces de decidir qué problema vale la pena resolver y bajo qué ética hacerlo.

Si estás trabajando en algún proyecto personal o aprendiendo una nueva tecnología, te recomiendo integrar estos conceptos. Al final, se trata de mejorar nuestra propia estructura de datos mental para procesar lo que viene.

¡Espero que esta información les sea útil!

---

Desde aquí un humano mas usando herramientas IA, generando contenido para otros humanos y para otras IA ... Nos vemos en el 2030 ...


https://youtu.be/dPBpCX7qW6s



viernes, 6 de febrero de 2026

La Hormiguita Cósmica

En un pequeño rincón del jardín, entre las hojas de una planta carnívora y el susurro de las mariposas, vivía Antonia, la más curiosa de todas las hormigas. Desde pequeña, soñaba con descubrir lo que había más allá de su mundo terrestre. Sus ojos, siempre brillantes, se fijaban en las estrellas cuando el sol se despedía y el cielo se teñía de violeta.

Un día, mientras recogía una semilla, Antonia encontró un objeto extraño: un brillante polvo de meteorito que le concedió la capacidad de volar. No era un vuelo ordinario; con cada pequeño salto sobre el polvo, su cuerpo se dilataba y se convertía en una diminuta nave de cristal, capaz de cruzar los límites del suelo.

—¡Voy a ver lo que hay más allá! —exclamó con emoción mientras se elevaba.

El polvo la llevó a un vacío sin gravedad. Antonia flotó libremente entre las nubes de vapor de la lluvia y los destellos de una luna recién nacida, y pronto descubrió que el espacio era su nuevo hogar. No había límites; solo infinitas posibilidades.

Mientras navegaba, se maravilló ante la inmensidad del cosmos:

  • Galaxias en espiral: se deslizó entre sus brazos como si fueran caminos de luz, observando estrellas naciendo y muriendo.
  • Sistemas solares: se acercó a planetas de colores vibrantes, donde descubrió formas de vida que no había imaginado. Un planeta de cristal le mostró su propio reflejo en un espejo líquido.
  • Agujeros negros: aunque temerosa al principio, la hormiguita vio cómo una esfera oscura devoraba la luz y aprendió a girar alrededor suyo sin ser arrastrada.



En cada paso, Antonia coleccionaba recuerdos de colores, sonidos y aromas que jamás había experimentado. Se dio cuenta de que el universo era un lienzo infinito, pintado con millones de historias.

Al final del día, cuando las estrellas comenzaron a brillar como diamantes en la noche, Antonia regresó al jardín. La nave se deshizo y ella volvió a su forma original, pero llevaba consigo una nueva perspectiva: el mundo no tenía que ser solo tierra firme y hojas verdes; podía ser un universo sin fin.


Desde entonces, cada vez que miraba hacia el cielo nocturno, Antonia sonreía sabiendo que, aunque pequeña, había viajado más allá de cualquier horizonte conocido. Y en su corazón, guardó la certeza de que cualquier sueño, por pequeño que sea, puede convertirse en una aventura cósmica.


jueves, 8 de enero de 2026

Reviviendo el Blog (y mis Fotos): La Guía Definitiva de Immich en Proxmox + OMV (Arquitectura "A prueba de Balas")

 

¡Hola, mundo! (Otra vez)

(Sopla el polvo del teclado... tose un poco).

Bueno, bueno. Si miramos el calendario, mi última publicación por aquí fue allá por Enero de 2024. Ha llovido bastante, la IA ha conquistado el mundo (hola, Gemini), y yo he estado hibernando... o mejor dicho, cacharreando.

Quiero arrancar este 2026 rompiendo la maldición del blog abandonado. Y qué mejor forma de hacerlo que compartiendo las batallas que he tenido montando mi propio HomeLab. Porque seamos honestos: no hay nada más gratificante (y frustrante a la vez) que ser tu propio SysAdmin.

Hoy vamos a hablar de Immich, esa maravilla para gestionar fotos que le da mil vueltas a Google Photos. Pero no vamos a hacer una instalación "siguiente-siguiente". No, señor. Vamos a montar una arquitectura robusta, limpia y recuperable.

El Objetivo: La Arquitectura "Plug & Play"

Mi obsesión era simple: Separar el cerebro de la memoria.

Quiero que Immich corra en un contenedor ligero (LXC) en Proxmox, pero que mis gigas y gigas de fotos vivan felices y seguras en mi NAS (OpenMediaVault).



¿Por qué? Porque si mañana explota mi contenedor de Immich (o si decido borrarlo porque me levanté con ganas de caos), quiero poder reinstalarlo en 5 minutos y que todas mis fotos sigan intactas en el NAS, esperando ser leídas. Sin duplicados. Sin dramas.

¿Suena bien? Pues agarra tu café, abre la terminal y vamos al lío.


📡 Fase 1: El Búnker (OpenMediaVault)

Lo primero es preparar el terreno en nuestro NAS. Necesitamos compartir la carpeta de fotos vía NFS, pero con un "hechizo" especial para que Docker no llore por los permisos.

  1. Identifica a tu dueño: Entra por SSH a tu OMV y averigua el UID/GID de tu usuario (el dueño de los datos).

    id tu_usuario
    # Quédate con estos números. Ej: uid=1000 gid=100
  2. La configuración NFS Mágica: Vete a Servicios > NFS > Recursos Compartidos. Crea uno apuntando a tu disco de datos. En el campo de Opciones, borra lo que haya y pega esto (es la clave del éxito):

    rw,subtree_check,insecure,all_squash,anonuid=1000,anongid=100

    💡 ¿Qué acabamos de hacer? Con all_squash, le decimos al NAS: "No me importa quién venga a escribir aquí (aunque sea un contenedor extraño), trátalo como si fuera el usuario 1000". ¡Adiós errores de permisos!


🌉 Fase 2: El Puente (Nodo Proxmox)

Aquí viene el truco pro. En lugar de luchar montando el NFS dentro del contenedor (que suele dar guerra en contenedores "Unprivileged"), lo montaremos en el "metal" (el Host Proxmox) y se lo pasaremos al contenedor.

⚠️ OJO: Estos comandos van en la consola de tu Nodo Proxmox (ej. aurora), no en el contenedor.

  1. Crea el punto de montaje:

    mkdir -p /mnt/pve/pinas-immich
  2. Edita el fstab para que sea persistente:

    nano /etc/fstab

    Agrega esto al final (usa la IP de tu OMV):

    100.100.100.45:/export/pinas-immich /mnt/pve/pinas-immich nfs defaults 0 0
  3. Monta y reza (bueno, mejor verifica):

    mount -a
  4. 🧪 La Prueba de Fuego: Vamos a ver si realmente podemos escribir.

    touch /mnt/pve/pinas-immich/test_host.txt && echo "¡ÉXITO!"
    rm /mnt/pve/pinas-immich/test_host.txt
    

    Si salió "¡ÉXITO!", seguimos. Si no, revisa la Fase 1.


📦 Fase 3: El Cerebro (LXC Container)

Vamos a crear el contenedor donde vivirá Immich.

  • Template: Debian 12 (Bookworm) - Lo clásico nunca falla.

  • Recursos: Dale cariño. 4 Cores y 4GB RAM mínimo (Immich usa Machine Learning, tiene hambre).

  • Unprivileged: SÍ. (Seguridad ante todo).

El Truco del Almendruco (Bind Mount): Antes de encender el contenedor, ejecuta esto en la consola del Nodo Proxmox (cambia 10X por el ID de tu nuevo contenedor):

pct set 10X -mp0 /mnt/pve/pinas-immich,mp=/mnt/pinas-immich

(Traducción: "Oye contenedor, la carpeta que tengo aquí, hazla aparecer allá adentro").

Ahora sí, inicia el contenedor, entra a su consola y haz otra prueba de fuego con touch para asegurarte de que heredó los poderes de escritura.


🧹 Fase 4: Limpieza Saiyajin (Staging)

Si vienes de una instalación anterior fallida o tienes una carpeta con fotos desordenadas, NO las importes directamente. Immich puede entrar en un bucle infinito de "leo foto, copio foto, leo la copia, copio la copia...".

Vamos a curarnos en salud dentro del LXC:

  1. Borra basura vieja: (Solo si tenías una instalación previa)

    cd /mnt/pinas-immich
    rm -rf thumbs/* encoded-video/* upload/* profile/*
    
  2. Elimina duplicados: (Seamos eficientes)

    apt update && apt install fdupes -y
    fdupes -r -d -N ./library
    
  3. La Zona de Paso (CRÍTICO): Saca todo de la carpeta library y ponlo en una carpeta temporal. Immich leerá de aquí y organizará en el destino final.

    mkdir -p import_source
    mv library/* import_source/
    # Tu carpeta 'library' debe quedar vacía como mi cuenta bancaria.
    

🐳 Fase 5: Docker e Immich

Ya tenemos la infraestructura. Ahora instalemos el software.

  1. Instala Docker:

    curl -fsSL https://get.docker.com -o get-docker.sh
    sh get-docker.sh
    
  2. Prepara Immich:

    mkdir -p /opt/immich && cd /opt/immich
    wget -O docker-compose.yml https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml
    wget -O .env https://github.com/immich-app/immich/releases/latest/download/example.env
    
  3. Edita el .env:

    nano .env

    Ajusta esto:

    UPLOAD_LOCATION=/mnt/pinas-immich
    DB_DATA_LOCATION=./postgres
    
  4. ¡Despegue! 🚀

    docker compose up -d

⚙️ Fase 6: Configuración del Storage Template

Antes de importar ni una sola foto, entra a la web (http://IP-LXC:2283), crea tu usuario admin y configura CÓMO quieres que se guarden los archivos.

Ve a Administration > Settings > Storage Template.

  • Enabled: ON

  • Template:

    {{filetype}}/{{y}}/{{y}}-{{MM}}-{{dd}}/{{filename}}

Nota importante: Usar {{filename}} al final asegura que Immich respete el nombre original de tu archivo y no le pegue un ID aleatorio feo al principio.


📥 Fase 7: La Gran Importación (CLI)

El momento de la verdad. Vamos a decirle a Immich: "Toma estos archivos desordenados de import_source y déjamelos bonitos en library".

Genera una API Key en tus ajustes de usuario y lanza esto en la terminal del LXC:

docker run -it --rm \
  -v "/mnt/pinas-immich:/import" \
  --network host \
  ghcr.io/immich-app/immich-cli:latest \
  upload \
  --key TU_API_KEY \
  --url http://localhost:2283/api \
  --recursive \
  /import/import_source

Si todo sale bien, verás una lluvia de texto verde confirmando la subida. Immich moverá tus fotos, las organizará por fecha y tu carpeta library quedará inmaculada.


Conclusión

Y ahí lo tienen. Una instalación de Immich que sobrevive a apocalipsis nucleares (o al menos a que borres el contenedor sin querer).

Espero que esta guía les sirva para perderle el miedo a mezclar Proxmox, LXC y NFS. Yo por ahora me despido, prometo no tardar otros dos años en volver a escribir... o quizás sí, depende de cuántos contenedores rompa la próxima semana.

Finalmente no olvides aplicar la estrategia de backups 3-2-1

¡Nos leemos en los comentarios! 👋