Volver al blog

Instalar Ollama y Open WebUI en un VPS Linux sin exponer su IA

Ejecute sus propios modelos de IA en un VPS Linux con Ollama y Open WebUI sin dejar la API abierta a Internet: escucha local, Nginx con HTTPS, cortafuegos y dimensionamiento de RAM y CPU.

Admin
Baie de serveurs câblés dans un datacenter, illustrant l'hébergement d'Ollama et Open WebUI sur un VPS Linux

Alojar su propia IA en un VPS Linux con Ollama y Open WebUI le permite conservar sus conversaciones en su servidor y dejar de pagar por petición. El problema: la API de Ollama no tiene ninguna autenticación, así que un puerto 11434 abierto en Internet es IA gratis para cualquiera. Esta guía le muestra una instalación en la que solo Nginx, con HTTPS, es accesible desde fuera.

Por qué una instancia de Ollama expuesta es un problema

Ollama ofrece una API REST muy práctica, pero sin contraseña ni clave. Cualquiera que alcance el puerto puede listar sus modelos, descargar otros nuevos hasta llenar el disco, borrarlos o lanzar generaciones que mantengan la CPU de su VPS al máximo. Los mantenedores consideran que la autenticación corresponde a un proxy inverso, así que le toca a usted añadirla.

El riesgo es real. En febrero de 2026, el buscador de filtraciones LeakIX contabilizaba más de 12.000 instancias de Ollama accesibles sin autenticación. Ese mismo año, un fallo de gravedad alta (CVE-2026-7482, apodado «Bleeding Llama») permitía leer la memoria de un servidor Ollama accesible sin ninguna credencial. Una instancia que solo escucha en local queda simplemente fuera del alcance de este tipo de ataque.

La arquitectura que vamos a montar

  • Ollama escucha solo en 127.0.0.1:11434.
  • Open WebUI funciona en Docker y escucha solo en 127.0.0.1:3000.
  • Nginx es el único servicio público: recibe el tráfico HTTPS en el puerto 443 y lo envía a Open WebUI.
  • El cortafuegos solo permite SSH, HTTP (para el certificado) y HTTPS.
  • Open WebUI gestiona las cuentas: un administrador y registros cerrados.

La guía supone un VPS Linux con Ubuntu 24.04 o Debian 12, acceso sudo, Docker ya instalado y un subdominio, por ejemplo ia.su-dominio.com, que apunte a la IP del servidor.

Qué VPS elegir: tabla de RAM y CPU sin GPU

En un VPS sin tarjeta gráfica, todo depende de la RAM y del número de núcleos. El modelo debe caber entero en memoria, con margen para el contexto de la conversación, Open WebUI (cuente con 1 GB aproximadamente) y el sistema. Los tamaños siguientes son los de las versiones por defecto (cuantizadas a 4 bits) publicadas en la biblioteca de Ollama.

VPSModelos realistasEjemplos (tamaño de descarga)Uso
4 GB de RAM, 2 vCPUDe 1 a 3 mil millones de parámetrosgemma3:1b (806 MB), qwen3:1.7b (1,4 GB), llama3.2:3b (2,0 GB)Pruebas, resúmenes cortos, pequeño asistente
8 GB de RAM, 3 vCPUHasta 4B con holgura, 8B posible pero justoqwen3:4b (2,5 GB), gemma3:4b (3,4 GB), qwen3:8b (5,2 GB)Uso personal diario
12 GB de RAM, 4 vCPU8B con holgura, 12-14B posible pero justoqwen3:8b (5,2 GB), gemma3:12b (8,2 GB), qwen3:14b (9,3 GB)Redacción, código, equipo pequeño
32 GB de RAM o más (servidor dedicado)De 27 a 32Bgemma3:27b (17 GB), qwen3:32b (20 GB)Mayor calidad, respuestas lentas sin GPU

En SoLinux, esto corresponde al VPS Linux 04G (4 GB, 2 núcleos, 45 GB NVMe), al VPS Linux 08G (8 GB, 3 núcleos, 50 GB NVMe) y al VPS Linux 12G (12 GB, 4 núcleos, 70 GB NVMe), sin permanencia, desde 7 € al mes para el 04G, disponibles en Francia, Alemania y Nueva York. Para un uso habitual, el 08G es el mejor punto de partida; el 12G compensa en cuanto quiera un modelo 8B con margen o varios usuarios.

Sea realista con la velocidad: sin GPU, un modelo 7-8B escribe su respuesta palabra a palabra, a unas pocas palabras por segundo, y la CPU se queda al 100 % durante la generación. Los modelos de 3-4B suelen ser el mejor equilibrio. El almacenamiento NVMe cuenta sobre todo en la carga inicial del modelo en memoria.

Paso 1: preparar el servidor y el cortafuegos

Empiece por actualizar el sistema y cierre todo lo que no sea imprescindible. Con UFW:

sudo apt update && sudo apt upgrade -y
sudo apt install -y ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose

Si prefiere usar nftables directamente (no junto con UFW), este es el equivalente mínimo para la cadena de entrada, en /etc/nftables.conf:

table inet filter {
  chain input {
    type filter hook input priority 0; policy drop;
    ct state established,related accept
    iif "lo" accept
    ip protocol icmp accept
    ip6 nexthdr icmpv6 accept
    tcp dport { 22, 80, 443 } accept
  }
}
sudo nft -c -f /etc/nftables.conf   # comprueba la sintaxis
sudo systemctl enable --now nftables

Trampa clásica: un puerto publicado por Docker con -p 3000:8080 queda abierto en todas las interfaces y se salta las reglas de UFW, porque Docker escribe sus propias reglas de cortafuegos. Por eso en esta guía no se publica ningún puerto de Docker.

Paso 2: instalar Ollama y mantenerlo en local

Ollama se instala en Linux con su script oficial, que crea un usuario ollama y un servicio systemd:

curl -fsSL https://ollama.com/install.sh | sh

Compruebe después que el servicio funciona:

ollama --version
sudo systemctl enable --now ollama
sudo systemctl status ollama

Por defecto, Ollama escucha en 127.0.0.1:11434. Muchos tutoriales le indican que ponga OLLAMA_HOST en 0.0.0.0 para que Docker lo alcance: eso es justo lo que expone la API. Fije en su lugar la dirección local de forma explícita, con un override de systemd que sobrevive a las actualizaciones:

sudo systemctl edit ollama

Añada estas líneas en la zona prevista:

[Service]
Environment="OLLAMA_HOST=127.0.0.1:11434"
Environment="OLLAMA_MAX_LOADED_MODELS=1"
Environment="OLLAMA_NUM_PARALLEL=1"

Las dos últimas variables limitan Ollama a un modelo cargado y una petición a la vez, lo que evita saturar la RAM en un VPS sin GPU. Recargue y compruebe la escucha:

sudo systemctl daemon-reload
sudo systemctl restart ollama
sudo ss -tlnp | grep 11434
# esperado: 127.0.0.1:11434, nunca 0.0.0.0:11434 ni [::]:11434
curl http://127.0.0.1:11434
# esperado: Ollama is running

Después, descargue un modelo adecuado para su VPS y pruébelo en la línea de comandos:

ollama pull qwen3:4b
ollama run qwen3:4b "Explica en una frase qué es un proxy inverso."
ollama list

Paso 3: lanzar Open WebUI con Docker, sin puerto público

El comando de inicio rápido de Open WebUI publica el puerto 3000 y llega a Ollama mediante host.docker.internal, lo que obliga a Ollama a escuchar en todas las interfaces. Nosotros lo hacemos de otro modo: el contenedor comparte la pila de red del host (--network=host), llega a Ollama por 127.0.0.1 y solo escucha en 127.0.0.1:3000 gracias a las variables HOST y PORT.

# clave secreta fija: sin ella, las sesiones se pierden en cada reinicio
sudo mkdir -p /etc/open-webui
openssl rand -hex 32 | sudo tee /etc/open-webui/secret > /dev/null
sudo chmod 600 /etc/open-webui/secret

DOMINIO=ia.su-dominio.com   # su subdominio

sudo docker run -d --name open-webui \
  --network=host \
  -e HOST=127.0.0.1 \
  -e PORT=3000 \
  -e OLLAMA_BASE_URL=http://127.0.0.1:11434 \
  -e WEBUI_SECRET_KEY="$(sudo cat /etc/open-webui/secret)" \
  -e CORS_ALLOW_ORIGIN="https://$DOMINIO" \
  -v open-webui:/app/backend/data \
  --restart always \
  ghcr.io/open-webui/open-webui:main

El volumen open-webui guarda las cuentas, las conversaciones y los ajustes. En producción puede sustituir la etiqueta main por un número de versión concreto para decidir usted cuándo actualizar. Compruebe la escucha al cabo de un minuto (el primer arranque tarda un poco):

sudo ss -tlnp | grep 3000
# esperado: 127.0.0.1:3000
curl -I http://127.0.0.1:3000

Paso 4: crear la cuenta de administrador antes de exponer nada

La primera cuenta creada en Open WebUI se convierte en administradora. No deje ese puesto a un desconocido que encuentre su subdominio antes que usted: créela antes de configurar Nginx, a través de un túnel SSH. Desde su ordenador:

ssh -L 3000:127.0.0.1:3000 usuario@IP_DEL_VPS

Abra después http://localhost:3000 en el navegador de su ordenador y cree la cuenta de administrador con una contraseña larga y única. Luego, en los ajustes de administración (sección de usuarios o de registros, según la versión):

  • desactive los nuevos registros;
  • si tiene que dejarlos abiertos un tiempo, mantenga el rol por defecto de los nuevos usuarios en pendiente (pending), para validar usted cada cuenta;
  • cree usted mismo las cuentas de sus colaboradores desde la gestión de usuarios.

No desactive nunca la autenticación (WEBUI_AUTH=False) en una instancia accesible desde Internet.

Paso 5: Nginx con HTTPS delante de Open WebUI

Instale Nginx y Certbot:

sudo apt install -y nginx certbot python3-certbot-nginx

Añada un límite de intentos de inicio de sesión en /etc/nginx/conf.d/limites.conf:

limit_req_zone $binary_remote_addr zone=owui_login:10m rate=5r/m;

Después cree /etc/nginx/sites-available/open-webui. Open WebUI usa WebSockets y transmite sus respuestas en continuo: necesita HTTP/1.1, las cabeceras Upgrade y el búfer desactivado; si no, las respuestas llegan de golpe o se cortan.

server {
    listen 80;
    server_name ia.su-dominio.com;

    client_max_body_size 50M;

    # limita los intentos de contraseña
    location = /api/v1/auths/signin {
        limit_req zone=owui_login burst=5 nodelay;
        proxy_pass http://127.0.0.1:3000;
        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;
    }

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        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;
        proxy_buffering off;
        proxy_cache off;
        proxy_read_timeout 1800s;
        proxy_send_timeout 1800s;
    }
}

Active el sitio, pruebe la configuración y solicite el certificado. Certbot añade por sí mismo el bloque HTTPS en el puerto 443 y la redirección desde HTTP:

sudo ln -s /etc/nginx/sites-available/open-webui /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
sudo certbot --nginx -d ia.su-dominio.com --redirect
sudo certbot renew --dry-run

Para un equipo pequeño, puede añadir una segunda barrera con auth_basic en el bloque location /, o limitar el acceso a unas pocas direcciones IP con allow y deny. Estas protecciones se suman a la cuenta de Open WebUI, no la sustituyen.

Comprobar que nada queda expuesto

En el servidor, liste los puertos en escucha: solo 22, 80 y 443 deben aparecer en una dirección pública.

sudo ss -tlnp

Desde su ordenador, pruebe la IP del VPS: los puertos 11434 y 3000 deben rechazar la conexión o no responder. Solo su subdominio en HTTPS, abierto en el navegador, debe mostrar la página de inicio de sesión.

nc -zv -w 3 IP_DEL_VPS 11434   # debe fallar
nc -zv -w 3 IP_DEL_VPS 3000    # debe fallar

Mantener la instalación al día

  • Ollama: vuelva a ejecutar el script de instalación oficial. Su override de systemd se conserva; aun así, compruebe la escucha con ss -tlnp tras cada actualización. El fallo CVE-2026-7482 está corregido desde la versión 0.17.1: compruebe la suya con ollama --version y no deje una versión antigua funcionando.
  • Open WebUI: docker pull de la imagen, luego docker stop, docker rm y el mismo comando docker run. El volumen conserva sus datos.
  • Copias de seguridad: guarde con regularidad el volumen open-webui (cuentas y conversaciones); los modelos se pueden volver a descargar.
  • Registros: journalctl -u ollama, docker logs open-webui y /var/log/nginx/ para detectar intentos de acceso repetidos.

Preguntas frecuentes

¿Hace falta una GPU para usar Ollama en un VPS?

No. Ollama funciona solo con la CPU. Las respuestas son más lentas que con una tarjeta gráfica, pero un modelo de 3 a 8 mil millones de parámetros es perfectamente utilizable en un VPS de 8 a 12 GB de RAM.

¿Cómo uso la API de Ollama desde otra máquina sin exponerla?

Mediante un túnel SSH: ssh -L 11434:127.0.0.1:11434 usuario@IP_DEL_VPS, y luego consulte http://localhost:11434 desde su ordenador. Para una aplicación de terceros, Open WebUI también puede generar claves de API por usuario, detrás de su Nginx con HTTPS.

Open WebUI no muestra ningún modelo, ¿qué hago?

Compruebe que ollama list devuelve modelos, que curl http://127.0.0.1:11434 responde y que el contenedor se lanzó con --network=host y OLLAMA_BASE_URL=http://127.0.0.1:11434. La conexión también se revisa en los ajustes de administración, en la sección de conexiones.

¿Cuántas personas pueden usarlo a la vez?

Sin GPU, cuente con una generación cada vez; las demás peticiones esperan su turno. Para dos o tres usuarios ocasionales basta un VPS 12G con un modelo 4B u 8B; más allá, se necesita un servidor dedicado con más núcleos y RAM.