Guía de despliegue

Cómo alojar LocalAI en un VPS

Desplegar en un VPS Cloud →

Tutorial

Cómo alojar LocalAI en un VPS

Inteligencia Artificial8 min de lectura8 pasos

LocalAI es un reemplazo de código abierto y compatible con la API de OpenAI: chat, embeddings, generación de imágenes y audio, todo ejecutado localmente. En su VPS se convierte en una API de IA polivalente y privada, que sus aplicaciones consumen sin cambiar su código. Esta guía cubre el despliegue completo con Docker Compose, la carga de modelos GGUF, la conexión de sus aplicaciones y la solución de los errores más comunes.

Contenido· Por qué autoalojar LocalAI en un VPS1/8
  1. 01Por qué autoalojar LocalAI en un VPS
  2. 02Los beneficios concretos de un LocalAI autoalojado
  3. 03Requisitos de hardware y software
  4. 04Desplegar LocalAI con Docker Compose y HTTPS
  5. 05Elegir y cargar sus modelos
  6. 06Conectar sus aplicaciones a LocalAI
  7. 07Solución de problemas: errores comunes
  8. 08LocalAI frente a Ollama frente a vLLM: ¿qué servidor LLM elegir?

Por qué autoalojar LocalAI en un VPS

Mientras Ollama se centra en el texto, LocalAI apunta a una compatibilidad amplia con la API de OpenAI: expone /v1/chat/completions, /v1/embeddings, /v1/images/generations e incluso la transcripción de audio, en una sola API. Para un equipo que ya tiene código escrito contra el SDK de OpenAI, LocalAI es un reemplazo casi transparente: cambia la URL base y la clave, y el resto funciona. En un VPS obtiene esa polivalencia sin dependencia externa ni coste por llamada. Resulta especialmente pertinente cuando necesita a la vez generación de texto, vectores para RAG y, puntualmente, imágenes, sin multiplicar proveedores ni claves.

Los beneficios concretos de un LocalAI autoalojado

  • Reemplazo directo de la API de OpenAI: ninguna reescritura del código cliente.
  • Una sola API para el chat, los embeddings, las imágenes y el audio.
  • Soporte de múltiples backends (llama.cpp, diffusers, whisper) bajo una interfaz unificada.
  • Formatos de modelos abiertos (GGUF) descargables e intercambiables.
  • Sin facturación por uso: un coste VPS fijo para todos los tipos de generación.
  • Datos y generaciones conservados íntegramente en su servidor.

Requisitos de hardware y software

Como LocalAI es polivalente, sus necesidades dependen de las funciones activadas. Las cifras siguientes son mínimos medidos — un VPS más potente reduce los tiempos de respuesta sin cambiar la viabilidad.

Solo texto, CPU, modelo 7B (p. ej. Mistral-7B-GGUF): 8 GB de RAM, 4 vCPU, 30 GB de disco. A este tamaño, una llamada a /v1/chat/completions tarda entre 5 y 15 segundos según la cuantización (Q4 es el equilibrio estándar). Un modelo 3B cabe en 4 GB de RAM.

Texto + imágenes (7B + Stable Diffusion): 16 GB de RAM, GPU recomendada, 50 GB de disco. Sin GPU, generar una imagen tarda varios minutos en CPU — prefiera un VPS con GPU para un uso habitual y la opción SINGLE_ACTIVE_BACKEND=true para evitar la saturación al combinar chat e imágenes en el mismo host CPU.

Software requerido: Docker 24+ y Docker Compose v2 (docker compose sin guión), un subdominio dedicado (p. ej. ia.su-dominio.com), el puerto 443 abierto, un registro DNS apuntando a la IP del VPS.

Desplegar LocalAI con Docker Compose y HTTPS

  1. Preparar la estructura de directorios

    Por SSH: mkdir -p /opt/localai/{models,config} && cd /opt/localai. La carpeta models recibirá los archivos GGUF; config recibirá los manifiestos YAML que describen cada modelo a LocalAI.

  2. Crear el archivo docker-compose.yaml

    Cree /opt/localai/docker-compose.yaml con el siguiente contenido:

    services:
      localai:
        image: localai/localai:latest-cpu
        restart: unless-stopped
        ports:
          - "127.0.0.1:8080:8080"
        volumes:
          - ./models:/build/models
          - ./config:/build/models
        environment:
          - MODELS_PATH=/build/models
          - SINGLE_ACTIVE_BACKEND=true
          - API_KEY=su-clave-secreta
        healthcheck:
          test: ["CMD", "curl", "-f", "http://localhost:8080/readyz"]
          interval: 30s
          retries: 3

    Reemplace latest-cpu por latest-gpu-nvidia-cuda-12 si su VPS dispone de una GPU NVIDIA. API_KEY activa la protección por token en todos los endpoints — sin esta variable, la API es accesible sin autenticación.

  3. Iniciar el contenedor

    Ejecute docker compose up -d, luego siga los logs de arranque: docker compose logs -f localai. Espere el mensaje LocalAI API is listening on [::]:8080 antes de continuar.

  4. Descargar un primer modelo desde la galería

    La galería de LocalAI agrupa más de 200 modelos preconfigurados. Para instalar Mistral-7B-Instruct cuantizado Q4:

    curl http://127.0.0.1:8080/models/apply \
      -H 'Authorization: Bearer su-clave-secreta' \
      -d '{"id": "huggingface@thebloke__mistral-7b-instruct-v0.2-gguf/mistral-7b-instruct-v0.2.Q4_K_M.gguf"}'

    Siga el progreso: curl http://127.0.0.1:8080/models/jobs/<job-id>. El GGUF se descarga en ./models/ y su manifiesto YAML se crea automáticamente en ./config/.

  5. Añadir un modelo de embeddings

    Para RAG, instale all-MiniLM-L6-v2 (84 MB, 256 MB de RAM):

    # config/all-minilm.yaml
    name: all-minilm
    backend: bert-embeddings
    parameters:
      model: all-MiniLM-L6-v2.gguf

    Descargue el GGUF manualmente en ./models/ desde HuggingFace, luego reinicie: docker compose restart localai. Verifique con curl http://127.0.0.1:8080/v1/models.

  6. Activar Whisper para la transcripción de audio

    Añada config/whisper.yaml:

    name: whisper-1
    backend: whisper
    parameters:
      model: whisper-base.en

    El modelo whisper-base (~142 MB) se descarga automáticamente en la primera llamada. Pruebe con:

    curl http://127.0.0.1:8080/v1/audio/transcriptions \
      -H 'Authorization: Bearer su-clave-secreta' \
      -F [email protected] -F model=whisper-1
  7. Configurar el reverse proxy Nginx y SSL

    Cree /etc/nginx/sites-available/localai:

    server {
      listen 443 ssl;
      server_name ia.su-dominio.com;
      ssl_certificate /etc/letsencrypt/live/ia.su-dominio.com/fullchain.pem;
      ssl_certificate_key /etc/letsencrypt/live/ia.su-dominio.com/privkey.pem;
      location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_read_timeout 300s;
        proxy_send_timeout 300s;
      }
    }

    Obtenga el certificado con certbot certonly --nginx -d ia.su-dominio.com, luego nginx -s reload. El timeout elevado es necesario para las inferencias largas en CPU.

  8. Probar la API vía HTTPS

    Valide el despliegue completo:

    curl https://ia.su-dominio.com/v1/chat/completions \
      -H 'Authorization: Bearer su-clave-secreta' \
      -H 'Content-Type: application/json' \
      -d '{"model": "mistral-7b-instruct-v0.2.Q4_K_M", "messages": [{"role": "user", "content": "Hola"}]}'

    Una respuesta JSON con un campo choices confirma que el despliegue funciona correctamente.

Active solo los backends que necesite. Cargar a la vez un modelo de chat, un modelo de embeddings y Stable Diffusion en un VPS CPU satura la RAM y hunde el rendimiento. Defina SINGLE_ACTIVE_BACKEND=true para mantener un único backend residente a la vez, y reserve la generación de imágenes a un VPS GPU si se convierte en un uso habitual.

Elegir y cargar sus modelos

LocalAI soporta varios formatos, pero el formato GGUF (producido por llama.cpp) es el estándar recomendado para CPU: está cuantizado (reduce el uso de RAM), es portable y está bien soportado por la galería.

GGUF vs otros formatos: los formatos GGUF son los únicos cargables directamente vía llama.cpp sin conversión previa. Los modelos Diffusers (imágenes) y ONNX (embeddings ligeros) tienen sus propios backends y no son intercambiables con los GGUF.

Galería vs descarga manual: la galería es la opción más sencilla — descarga el GGUF y genera el YAML de configuración automáticamente. Para un modelo no listado en la galería (un modelo ajustado, un GGUF personalizado), deposite el archivo en ./models/ y cree el YAML manualmente:

name: mi-modelo
backend: llama
parameters:
  model: mi-modelo.Q4_K_M.gguf
context_size: 4096

Listar los modelos cargados:

curl https://ia.su-dominio.com/v1/models \
  -H 'Authorization: Bearer su-clave-secreta'

Los modelos cuyo YAML está presente en ./config/ aparecen en la lista, incluso si su GGUF aún no se ha descargado — en ese caso, la primera llamada desencadena la descarga.

Conectar sus aplicaciones a LocalAI

Al ser LocalAI compatible con la API de OpenAI, migrar una aplicación existente se reduce a dos cambios: la URL base y la clave.

Python (openai SDK):

import openai

client = openai.OpenAI(
    base_url="https://ia.su-dominio.com/v1",
    api_key="su-clave-secreta"
)

response = client.chat.completions.create(
    model="mistral-7b-instruct-v0.2.Q4_K_M",
    messages=[{"role": "user", "content": "Resume este texto: ..."}]
)
print(response.choices[0].message.content)

Node.js (openai SDK):

import OpenAI from 'openai';

const client = new OpenAI({
  baseURL: 'https://ia.su-dominio.com/v1',
  apiKey: 'su-clave-secreta'
});

const completion = await client.chat.completions.create({
  model: 'mistral-7b-instruct-v0.2.Q4_K_M',
  messages: [{ role: 'user', content: 'Hola' }]
});
console.log(completion.choices[0].message.content);

curl directo:

curl https://ia.su-dominio.com/v1/embeddings \
  -H 'Authorization: Bearer su-clave-secreta' \
  -H 'Content-Type: application/json' \
  -d '{"model": "all-minilm", "input": "Texto a vectorizar"}'

Las bibliotecas LangChain, LlamaIndex y la mayoría de los frameworks RAG aceptan un parámetro openai_api_base o base_url — el cambio es idéntico.

Solución de problemas: errores comunes

404 model not found o model not loaded: el nombre de modelo pasado en model: no coincide con ningún manifiesto YAML en ./config/. Compruebe con GET /v1/models: el nombre mostrado debe usarse exactamente tal cual. Si el modelo no aparece, verifique que el YAML esté en la carpeta montada y reinicie el contenedor.

Inferencia muy lenta o killed (OOM): el modelo supera la RAM disponible. Un modelo 7B Q4 requiere aproximadamente 6 GB de RAM libre en el momento de la carga. Compruebe con docker stats localai durante una inferencia. Soluciones: pasar a una cuantización más ligera (Q3_K_S o Q2_K), reducir el context_size en el YAML, o actualizar el VPS.

SINGLE_ACTIVE_BACKEND error: LocalAI está configurado con SINGLE_ACTIVE_BACKEND=true y una petición intenta cargar un segundo modelo mientras otro está activo. Es el comportamiento esperado en CPU. Espere a que termine la primera inferencia, o desactive la opción si su VPS tiene suficiente RAM para varios modelos simultáneos.

GPU no detectada (CUDA device not found): verifique que está usando la imagen latest-gpu-nvidia-cuda-12, que el driver NVIDIA está instalado en el host (nvidia-smi), y que el contenedor tiene acceso a la GPU (gpus: all en docker-compose.yaml bajo la clave deploy:). Sin estas tres condiciones, LocalAI vuelve silenciosamente a CPU.

401 Unauthorized: la variable API_KEY está definida en docker-compose.yaml pero la cabecera Authorization: Bearer <clave> está ausente o incorrecta en la llamada. Todos los endpoints, incluido /v1/models, requieren la cabecera en cuanto API_KEY está establecido.

LocalAI frente a Ollama frente a vLLM: ¿qué servidor LLM elegir?

Desplace la tabla

LocalAIOllamavLLM
GPU requeridaNo (CPU por defecto)No (CPU por defecto)Sí (GPU obligatoria)
API compatible con OpenAISí (completa)Sí (parcial)Sí (completa)
Generación de imágenesSí (Stable Diffusion)NoNo
Transcripción de audioSí (Whisper)NoNo
Embeddings nativosSíSíSí
Biblioteca de modelosMás de 200 modelos GGUFLista de modelos seleccionadosModelos HuggingFace
Rendimiento (tokens/s, 7B)~10-20 CPU / ~80+ GPU~15-25 CPU / ~80+ GPU~150+ solo GPU
RAM (modelo 7B Q4)~6 GB~6 GB~14 GB (FP16)
Caso de uso principalAPI unificada multimodalInferencia de texto simpleProducción de alto rendimiento

Una API de IA completa y privada en un VPS Cloud ServOrbit

Con un VPS Cloud de ServOrbit y Docker preconfigurado, despliegue LocalAI como alternativa privada a la API de OpenAI. Elija una configuración CPU o GPU según sus necesidades de chat, embeddings o imágenes.

¿Necesita ayuda?

Consulte nuestro centro de ayuda y nuestra FAQ, o contacte con nuestro equipo: llamada, WhatsApp o correo electrónico. Soporte en francés, inglés y árabe.

Escribir por WhatsAppse abre en una pestaña nueva