Open WebUI es una interfaz web de código abierto, similar a ChatGPT, para conversar con modelos de lenguaje que se ejecutan en tu propio servidor a través de Ollama o de cualquier API compatible con OpenAI. Incluye cuentas de usuario con roles, historial de conversaciones y consulta de documentos (RAG). En este tutorial desplegarás Open WebUI con Docker Compose en Ubuntu 24.04, lo conectarás a una instalación de Ollama en el mismo servidor y lo publicarás con Nginx y un certificado de Let's Encrypt.

Requisitos previos

Para seguir esta guía necesitas:

  • Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath, con al menos 8 GB de RAM para modelos pequeños (3B a 8B parámetros). Con GPU NVIDIA las respuestas son mucho más rápidas, pero no es obligatoria.
  • Un usuario no root con privilegios sudo y el cortafuegos UFW activo con SSH permitido.
  • Docker Engine y el plugin de Docker Compose instalados desde el repositorio oficial de Docker.
  • Ollama instalado en el servidor como servicio systemd (el instalador oficial de ollama.com crea la unidad ollama.service).
  • Un dominio con un registro A que apunte a la IP del servidor. En esta guía se usa chat.your_domain; sustitúyelo por el tuyo.
  • Nginx instalado (sudo apt install nginx) y los puertos 80 y 443 abiertos.

Paso 1: Preparar Ollama para aceptar conexiones desde Docker

Por defecto Ollama solo escucha en 127.0.0.1:11434. El contenedor de Open WebUI no comparte ese loopback con el host, así que Ollama debe escuchar también en la interfaz puente de Docker.

Crea un override de la unidad systemd de Ollama:

sudo systemctl edit ollama

Añade estas líneas en la zona indicada del editor y guarda:

[Service]
Environment="OLLAMA_HOST=0.0.0.0:11434"

Aplica el cambio:

sudo systemctl daemon-reload
sudo systemctl restart ollama

Ahora Ollama escucha en todas las interfaces. UFW bloquea por defecto las conexiones entrantes, así que permite el puerto 11434 solo desde las redes privadas que usa Docker y no desde Internet:

sudo ufw allow from 172.16.0.0/12 to any port 11434 proto tcp

Descarga un modelo si todavía no tienes ninguno. llama3.2 (3B parámetros) funciona bien en CPU:

ollama pull llama3.2

Comprueba que Ollama responde y que el modelo está disponible:

curl http://127.0.0.1:11434/api/tags

La respuesta es un JSON con la lista de modelos:

{"models":[{"name":"llama3.2:latest","model":"llama3.2:latest", ... }]}

Paso 2: Crear el archivo de Docker Compose

Crea un directorio para el proyecto:

sudo mkdir -p /opt/open-webui
cd /opt/open-webui

Genera una clave secreta aleatoria para firmar las sesiones y guárdala en un archivo .env que solo pueda leer root:

echo "WEBUI_SECRET_KEY=$(openssl rand -hex 32)" | sudo tee /opt/open-webui/.env > /dev/null
sudo chmod 600 /opt/open-webui/.env

Crea el archivo docker-compose.yml:

sudo nano /opt/open-webui/docker-compose.yml

Pega esta configuración:

services:
  open-webui:
    image: ghcr.io/open-webui/open-webui:main
    container_name: open-webui
    restart: unless-stopped
    ports:
      - "127.0.0.1:3000:8080"
    volumes:
      - open-webui:/app/backend/data
    env_file: .env
    environment:
      - OLLAMA_BASE_URL=http://host.docker.internal:11434
      - WEBUI_URL=https://chat.your_domain
    extra_hosts:
      - "host.docker.internal:host-gateway"

volumes:
  open-webui:

Puntos importantes de esta configuración:

  • 127.0.0.1:3000:8080 publica el puerto solo en el loopback. Docker inserta sus propias reglas de iptables y se salta UFW, así que publicar en 0.0.0.0 dejaría la interfaz accesible sin HTTPS desde cualquier sitio.
  • host.docker.internal apunta a la IP del host gracias a host-gateway, y así el contenedor llega al Ollama del paso anterior.
  • El volumen open-webui guarda la base de datos, los usuarios, los chats y los documentos subidos.

Paso 3: Arrancar Open WebUI

Descarga la imagen y arranca el contenedor en segundo plano:

sudo docker compose up -d

El primer arranque tarda uno o dos minutos porque Open WebUI descarga el modelo de embeddings que usa para RAG. Sigue los logs hasta ver que Uvicorn está escuchando:

sudo docker compose logs -f open-webui
open-webui  | INFO:     Uvicorn running on http://0.0.0.0:8080 (Press CTRL+C to quit)

Pulsa Ctrl+C para salir de los logs y comprueba el endpoint de salud:

curl http://127.0.0.1:3000/health
{"status":true}

Verifica también que el contenedor llega a Ollama:

sudo docker exec open-webui curl -s http://host.docker.internal:11434/api/version
{"version":"0.x.y"}

Si este último comando no devuelve nada, revisa la regla de UFW y el override del paso 1.

Paso 4: Publicar Open WebUI con Nginx y HTTPS

Crea un bloque de servidor para el dominio:

sudo nano /etc/nginx/sites-available/open-webui

Open WebUI transmite las respuestas del modelo por WebSocket, así que el proxy debe reenviar las cabeceras Upgrade y Connection y tolerar respuestas largas:

server {
    listen 80;
    listen [::]:80;
    server_name chat.your_domain;

    client_max_body_size 100M;

    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_read_timeout 300s;
    }
}

client_max_body_size 100M permite subir documentos grandes para RAG. Activa el sitio y comprueba la sintaxis:

sudo ln -s /etc/nginx/sites-available/open-webui /etc/nginx/sites-enabled/
sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Recarga Nginx y abre los puertos web en UFW:

sudo systemctl reload nginx
sudo ufw allow 'Nginx Full'

Instala Certbot y obtén el certificado. El plugin de Nginx añade la configuración TLS y la redirección de HTTP a HTTPS al bloque que acabas de crear:

sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d chat.your_domain

Comprueba que el sitio responde por HTTPS:

curl -I https://chat.your_domain
HTTP/2 200
server: nginx/1.24.0 (Ubuntu)
content-type: text/html; charset=utf-8

Paso 5: Crear la cuenta de administrador y controlar los registros

Abre https://chat.your_domain en el navegador y regístrate. La primera cuenta que se crea recibe automáticamente el rol de administrador, así que hazlo inmediatamente después de publicar el sitio.

A partir de ahí, las cuentas nuevas quedan con el rol pending (pendiente) y no pueden usar el chat hasta que un administrador las apruebe. Para gestionar el acceso, entra en Panel de administración > Usuarios, donde puedes aprobar cuentas pendientes y cambiar roles entre user y admin.

Si nadie más debe poder registrarse, desactiva el formulario de registro en Panel de administración > Configuración > General. Los administradores pueden seguir creando cuentas a mano desde la sección de usuarios.

Para probar el chat, abre una conversación nueva, selecciona llama3.2:latest en el selector de modelos de la parte superior y envía un mensaje. Si el selector aparece vacío, revisa la conexión en Panel de administración > Configuración > Conexiones; la URL de Ollama debe ser http://host.docker.internal:11434.

Paso 6: Consultar documentos con RAG

Open WebUI puede responder usando el contenido de tus propios documentos. Por defecto calcula los embeddings dentro del contenedor con un modelo de sentence-transformers, lo que funciona sin configuración adicional.

Para usarlo, pulsa el botón + del cuadro de mensaje, adjunta un PDF, DOCX o TXT y haz una pregunta sobre su contenido. Si quieres que un conjunto de documentos esté disponible de forma permanente, créalo como base de conocimiento en Espacio de trabajo > Conocimiento y haz referencia a él en el chat escribiendo # seguido de su nombre.

Si prefieres que Ollama calcule los embeddings, descarga un modelo de embeddings:

ollama pull nomic-embed-text

Después, en Panel de administración > Configuración > Documentos, cambia el motor de embeddings a Ollama y selecciona nomic-embed-text. Los documentos ya indexados deben volver a procesarse tras el cambio.

Paso 7: Actualizar Open WebUI

La etiqueta main apunta siempre a la última versión publicada. Para actualizar, descarga la imagen nueva y recrea el contenedor; los datos se conservan en el volumen:

cd /opt/open-webui
sudo docker compose pull
sudo docker compose up -d

Antes de actualizar conviene hacer una copia del volumen, porque algunas versiones migran el esquema de la base de datos:

sudo docker run --rm -v open-webui_open-webui:/data -v /root:/backup alpine tar czf /backup/open-webui-backup.tar.gz -C /data .

El nombre del volumen lleva como prefijo el nombre del proyecto de Compose (el directorio open-webui). Puedes confirmarlo con sudo docker volume ls.

Solución de problemas

El selector de modelos está vacío o aparece un error de conexión con Ollama. Comprueba desde el contenedor que Ollama responde con el comando docker exec del paso 3. Si falla, confirma que Ollama escucha en todas las interfaces con sudo ss -tlnp | grep 11434 (debe aparecer *:11434 o 0.0.0.0:11434) y que la regla de UFW para 172.16.0.0/12 existe con sudo ufw status.

Las respuestas se cortan o no aparecen en tiempo real. Suele ser el proxy. Revisa que el bloque de Nginx incluye las cabeceras Upgrade y Connection y proxy_buffering off, y consulta los errores con sudo tail -n 50 /var/log/nginx/error.log.

Las respuestas son muy lentas. En CPU, un modelo de 8B parámetros puede tardar varios segundos por frase. Prueba un modelo más pequeño (llama3.2:1b) o usa un servidor con GPU. Con ollama ps puedes ver si el modelo está cargado en GPU o en CPU.

El contenedor se reinicia en bucle. Consulta los logs con sudo docker compose logs --tail 100 open-webui. Un error frecuente es quedarse sin espacio en disco durante la descarga del modelo de embeddings; compruébalo con df -h.

Conclusión

Ya tienes Open WebUI funcionando con Docker Compose, conectado a Ollama y publicado con HTTPS, con registro controlado por un administrador y soporte para consultar documentos. Como siguientes pasos, puedes añadir conexiones a APIs compatibles con OpenAI (por ejemplo, un servidor vLLM) en Panel de administración > Configuración > Conexiones, programar copias periódicas del volumen de datos y configurar el acceso con SSO si tu organización ya usa un proveedor OIDC.