Alternativas a Open WebUI para un VPS con IP pública
Compara Open WebUI, LibreChat, Hollama y OrionChat en un VPS: RAM disponible para el modelo, inicios de sesión, Ollama remoto y mantenimiento.
Qué alternativa a Open WebUI conviene usar en un VPS
Las alternativas a Open WebUI casi siempre se comparan en un portátil, donde la RAM es barata y ningún servicio escucha en una dirección pública. Un VPS cambia ambos aspectos, y eso modifica la clasificación. Open WebUI sigue siendo la opción predeterminada adecuada en cuanto inicia sesión una segunda persona, porque incluye cuentas de usuario reales y un panel de administración. Los proyectos más ligeros ganan cuando la interfaz compite con el modelo por el último gigabyte de RAM. El precio de esa ventaja es la autenticación: no incluyen ninguna.
Todo lo siguiente procede de la documentación de cada proyecto, consultada en agosto de 2026, revisada de nuevo el 20 de octubre de 2026 y comprobada otra vez para Open WebUI, LibreChat, Hollama y OrionChat el 25 de octubre de 2026. La documentación de Ollama y las reglas de seguridad del navegador se revisaron de nuevo el 29 de octubre de 2026. Los cuatro ejes son los que sólo aparecen cuando el servidor es accesible desde Internet.
Cuatro aspectos que sólo importan en una IP pública
- Memoria junto al modelo. El servidor del modelo es el proceso que más recursos consume en el equipo. Cada megabyte que usa la interfaz es un megabyte que no puede usar el modelo.
- Autenticación. Algunos de estos proyectos tienen cuentas de usuario y roles. Otros dan por hecho que son lo único que se ejecuta en el portátil y no tienen ningún inicio de sesión.
- Inferencia remota. Una interfaz que sólo apunta a
127.0.0.1:11434espera que el modelo esté en el mismo equipo que la interfaz. Si el modelo está en otro lugar, se necesita un túnel que reenvíe ese puerto local al host del modelo. - Mantenimiento. Un contenedor con un archivo SQLite requiere una gestión distinta de seis contenedores con MongoDB y una base de datos vectorial detrás.
Cuánta RAM deja el modelo para la interfaz
La interfaz no es lo que más memoria consume en el servidor. El modelo sí. Los tamaños de descarga publicados indican el mínimo, porque los pesos deben permanecer en memoria mientras el modelo responde. El uso real de memoria es mayor que el tamaño de descarga una vez asignada la caché de contexto.
Los datos de este gráfico
[
{
"label": "llama3.2:3b",
"download_gb": "2.0"
},
{
"label": "qwen3:4b",
"download_gb": "2.5"
},
{
"label": "gemma3:4b",
"download_gb": "3.4"
},
{
"label": "qwen3:8b",
"download_gb": "5.2"
}
]Esas son las cifras que mostraban las páginas de la biblioteca de Ollama el 25 de octubre de 2026. Son tamaños publicados, no mediciones. En un VPS de 4 GB, qwen3:4b con 2.5 GB deja menos de 1.5 GB para el sistema operativo y todo lo demás. La caché de contexto consume parte de esa memoria a medida que crece la conversación. Por eso el valor de num_ctx que configure es una decisión de memoria además de una decisión de calidad. qwen3:8b con 5.2 GB no cabe en ese servidor. Esta es la situación que los análisis de portátiles nunca cubren. También es el punto en el que una interfaz de chat que ocupa unos cientos de megabytes determina si el modelo puede ejecutarse. Si está dimensionando un servidor para algo muy superior a estas etiquetas, el cálculo para un modelo 27B en un VPS que usa sólo la CPU muestra lo rápido que la interfaz deja de ser el factor decisivo.
Mida el uso en lugar de confiar en cualquier cifra de un análisis, incluida esta. Ejecute docker stats --no-stream una hora después de comenzar a usarlo de forma real, no un minuto después de iniciar el contenedor, porque la memoria relevante se asigna durante el primer uso. Ollama también libera los pesos tras cinco minutos de inactividad. Por tanto, una lectura tomada entre conversaciones subestima el pico. El siguiente mensaje debe cargar todo el modelo otra vez, a menos que mantenga el modelo residente mediante keep_alive.
Open WebUI: sigue siendo la opción predeterminada para más de un usuario
Open WebUI se ejecuta a partir de una imagen y conserva sus datos en un volumen.
docker run -d -p 127.0.0.1:3000:8080 -v open-webui:/app/backend/data --name open-webui --restart always ghcr.io/open-webui/open-webui:mainEl comando del README del proyecto publica -p 3000:8080, que escucha en todas las interfaces. El prefijo 127.0.0.1: lo mantiene en loopback. En un VPS, ese prefijo importa más que cualquier otra parte de la línea, porque Docker escribe sus propias reglas de iptables y un puerto publicado ignora las reglas de denegación de ufw.
Acceda a la página mediante un túnel o un proxy, descritos más abajo, y cree la primera cuenta. Esa cuenta se convierte en el administrador. Después, el registro de cuentas se desactiva hasta que un administrador vuelva a activar New Sign Ups. Las cuentas posteriores se crean con el rol pending, el valor predeterminado documentado de DEFAULT_USER_ROLE. Por tanto, un usuario ajeno que acceda a la página todavía no puede usar su modelo hasta que un administrador lo apruebe.
Open WebUI consume más memoria que los proyectos siguientes porque ofrece más funciones, y su propia página de rendimiento identifica los componentes responsables de ese consumo. El motor de embeddings predeterminado carga un modelo de sentence-transformers dentro del contenedor. La documentación indica un consumo aproximado de 500 MB o más por proceso de trabajo. RAG_EMBEDDING_ENGINE=ollama delega esa tarea en el servidor de modelos que ya ejecuta. AUDIO_STT_ENGINE=webapi evita cargar un modelo local de conversión de voz a texto. En SQLite, si DATABASE_POOL_SIZE no está definido, el pool recurre a un tamaño interno grande y cada conexión crea su propia caché de páginas y su propio mapa de memoria. Por eso, en un equipo pequeño, establezca DATABASE_POOL_SIZE=8 y DATABASE_SQLITE_PRAGMA_MMAP_SIZE=0. Autocomplete solicita al modelo una finalización mientras el usuario todavía escribe. Ahora se distribuye desactivado (ENABLE_AUTOCOMPLETE_GENERATION tiene False como valor predeterminado), así que manténgalo desactivado en un equipo pequeño.
LibreChat: multiusuario, con una pila detrás
git clone https://github.com/danny-avila/LibreChat.git
cd LibreChat
cp .env.example .env
docker compose up -dLa interfaz responde en el puerto 3080. LibreChat es la opción adecuada cuando necesita un sistema de identidades en lugar de un simple formulario de inicio de sesión: documenta inicios de sesión mediante LDAP y OAuth2, y su archivo compose predeterminado también define un panel de administración para usuarios, grupos y roles. El panel no se inicia de forma predeterminada. No inicia hasta que se establece ADMIN_PANEL_SESSION_SECRET en .env. Es un valor obligatorio de al menos 32 caracteres y no tiene un valor predeterminado. Genérelo con openssl rand -hex 32 si lo necesita. El panel se ejecuta como un servicio independiente, no dentro del proceso de LibreChat. Requiere LibreChat v0.8.5 o posterior, y el proyecto todavía lo marca como una vista previa. Esta capacidad se incorpora mediante una pila.
Los datos de este gráfico
[
{
"label": "OrionChat",
"containers": 0,
"notes": "static files, served by a web server you already run"
},
{
"label": "Hollama",
"containers": 1,
"notes": "one container serving a browser app"
},
{
"label": "Open WebUI",
"containers": 1,
"notes": "application and SQLite in one image"
},
{
"label": "LibreChat",
"containers": 5,
"notes": "api, MongoDB, Meilisearch, pgvector, RAG API"
}
]El archivo compose predeterminado inicia 5 servicios: api, MongoDB, Meilisearch, pgvector, RAG API. Un sexto servicio, el panel de administración, está en el mismo archivo y se une a ellos cuando se establece su secreto. Ninguno de ellos es el modelo. MongoDB y pgvector necesitan memoria propia, y en un equipo con 4 GB esa es memoria que necesita el modelo.
Dos servicios del archivo publican puertos y ninguna asignación especifica una dirección de enlace: la API en 3080 y el panel de administración en el puerto 3000 del host, el valor predeterminado de ADMIN_PANEL_PORT. Por tanto, ambos escuchan en todas las interfaces cuando se ejecutan. Open WebUI también usa el puerto 3000, por lo que ambos servicios entran en conflicto en un equipo compartido en cuanto se habilita el panel. Cambie ambos a 127.0.0.1 en docker-compose.override.yml antes de exponer la pila a Internet.
Las actualizaciones se realizan mediante una operación de git. Esta es la parte que suele hacerse mal.
docker compose down
git pull
docker compose pull
docker compose up -dgit pull se detiene con un conflicto si modificó el archivo versionado docker-compose.yml. En ese caso, la actualización queda aplicada sólo parcialmente. Guarde sus cambios en docker-compose.override.yml, que el proyecto proporciona para este fin, y mantenga los secretos en .env. Ambos archivos no están versionados, por lo que git pull no los modifica.
Configure LibreChat para usar su propio servidor de modelos mediante un endpoint personalizado en librechat.yaml.
endpoints:
custom:
- name: "Ollama"
apiKey: "ollama"
baseURL: "http://model-host:11434/v1/"
models:
default: ["llama3.2"]
fetch: true
titleConvo: true
titleModel: "current_model"
modelDisplayLabel: "Ollama"Sustituya model-host por la dirección del equipo que ejecuta Ollama. El campo apiKey debe estar presente aunque Ollama ignore su valor, por lo que puede usar un marcador de posición. Si LibreChat se ejecuta en Docker y Ollama se ejecuta en el mismo equipo, localhost dentro del contenedor hace referencia al propio contenedor. En ese caso, use host.docker.internal.
Hollama y OrionChat: el navegador hace el trabajo
Hollama sirve una aplicación web desde un contenedor pequeño. Los chats se almacenan en el navegador, no en el servidor.
docker run -d --restart unless-stopped -p 127.0.0.1:4173:4173 --name hollama ghcr.io/fmaclen/hollama:latestLa versión del README de este comando usa --rm, que elimina el contenedor cuando se detiene, por lo que la interfaz nunca vuelve a estar disponible después de un reinicio.
OrionChat va más allá y no tiene ningún componente en el servidor. Clone el repositorio y sirva la carpeta con el servidor web que ya utiliza, o abra index.html desde el disco. Las claves de API se almacenan en localStorage del navegador, el historial de chats permanece en el navegador y la aplicación elimina los chats más antiguos cuando el recuento supera 512. La dirección de Ollama de OrionChat está fijada en su código fuente (js/script.js) en http://localhost:11434, y su configuración no tiene ningún campo para cambiarla.
Ninguno de los dos proyectos tiene inicio de sesión. En un portátil, esto no supone un problema. En un VPS, significa que la página nunca debe publicarse en 0.0.0.0, y también implica algo fácil de pasar por alto: el navegador llama al modelo, no el servidor.
Ese hecho determina dónde se pueden utilizar. El navegador debe poder acceder directamente a Ollama. En OrionChat, eso siempre significa localhost:11434 en la máquina donde se ejecuta el navegador, por lo que en un VPS el túnel SSH siguiente es su única ruta hacia el modelo. Hollama acepta cualquier dirección que introduzca como URL base de la conexión, y su guía de self-hosting contempla un servidor Ollama en otro dispositivo: añada el origen de Hollama a OLLAMA_ORIGINS en el lado de Ollama. Por tanto, salvo que reenvíe el puerto mediante SSH, Ollama debe escuchar en algo más que loopback, y la API de Ollama no requiere inicio de sesión ni clave. De esto se derivan dos reglas para el navegador. Una página servida mediante HTTPS no puede llamar a un endpoint HTTP sin cifrar en una dirección IP pública, y la consola muestra Mixed Content: The page at 'https://chat.example.com/' was loaded over HTTPS, but requested an insecure resource 'http://203.0.113.10:11434/api/tags'. This request has been blocked.. Loopback tiene una excepción independiente: la especificación Mixed Content sólo bloquea las URL que no son potencialmente confiables, y la especificación Secure Contexts considera localhost, 127.0.0.0/8 y ::1 potencialmente confiables, por lo que la misma página HTTPS puede llamar a http://localhost:11434 o http://127.0.0.1:11434. Esa excepción es la que utiliza el túnel SSH siguiente. Desde la versión 142, Chrome añade un paso cuando la página procede de un sitio público como https://chat.example.com: una solicitud desde ese sitio a una dirección de loopback o de la red local espera hasta que el usuario permita el acceso a la red local en un cuadro de diálogo de permisos. Chrome también exime las solicitudes HTTP sujetas a permisos dirigidas a endpoints de la red local de las comprobaciones de contenido mixto cuando el nombre de host es un literal de IP privada como 192.168.0.1, un nombre .local, o la solicitud fetch especifica targetAddressSpace: "local". Una página que abra en http://localhost mediante el túnel ya está en loopback, por lo que ese cuadro de diálogo no se aplica. Una llamada a cualquier otro origen se rechaza con has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource hasta que permita ese origen.
La forma documentada de Ollama para cambiar cualquiera de estos ajustes es utilizar un override de systemd.
sudo systemctl edit ollama.service[Service]
Environment="OLLAMA_HOST=0.0.0.0:11434"
Environment="OLLAMA_ORIGINS=https://chat.example.com"sudo systemctl daemon-reload
sudo systemctl restart ollama
sudo ss -lntp | grep 11434ss ahora debería mostrar 0.0.0.0:11434 donde antes mostraba 127.0.0.1:11434. Haga este cambio sólo cuando un firewall o un proxy con autenticación ya controle quién puede acceder al puerto, porque un puerto 11434 abierto expone un servidor de modelos y los escáneres masivos alcanzan rápidamente un puerto público nuevo. El túnel SSH siguiente evita completamente esta cuestión: la página se ejecuta entonces en un origen localhost, que Ollama permite de forma predeterminada, y el puerto nunca sale del equipo.
¿Puede cada uno usar un endpoint remoto de Ollama o vLLM?
Open WebUI puede hacerlo, y la conexión se establece en el servidor. OLLAMA_BASE_URL=http://model-host:11434 lo dirige a Ollama. Para vLLM, configure OPENAI_API_BASE_URL=http://model-host:8000/v1 y conserve /v1, que es la ruta en la que vLLM expone su API. Configure OPENAI_API_KEY sólo si el servidor se inició con una clave, ya que la guía de Open WebUI para vLLM no usa autenticación de forma predeterminada. Los demás servidores compatibles con OpenAI usan la ruta base que indiquen sus propios documentos, que no siempre es /v1. OPENAI_API_BASE_URLS acepta varios backends separados por punto y coma.
LibreChat puede hacerlo mediante baseURL del endpoint personalizado mostrado arriba. Esa petición también sale del servidor, por lo que no se aplica ninguna regla del navegador. La misma URL base y la misma clave de marcador de posición funcionan fuera de una ventana de chat, lo que basta para dirigir un agente de programación al modelo que ya aloja.
Hollama puede apuntar a cualquier endpoint que introduzca en su configuración. Su conexión con Ollama tiene una URL base editable que usa http://localhost:11434 de forma predeterminada. Además, Hollama ofrece una conexión compatible con OpenAI, http://localhost:8080/v1 de forma predeterminada, que es la ruta para vLLM. La petición sale del navegador, por lo que todo lo indicado en la sección anterior se aplica también aquí. OrionChat no se puede dirigir a otro endpoint. Sus endpoints están codificados de forma fija: Ollama usa http://localhost:11434/v1/chat/completions. Su README indica que las peticiones van directamente a la API oficial de cada proveedor. Un Ollama remoto sólo es accesible mediante un túnel SSH que haga que responda en ese puerto local. No existe ninguna opción para un servidor vLLM.
Separar la interfaz del modelo es la ventaja más útil que ofrece un endpoint remoto. Coloque la interfaz en un equipo pequeño y el modelo donde haya memoria disponible. Este también es el momento de decidir si Ollama o vLLM debe atender las peticiones, porque ambos se comportan de forma muy diferente cuando varias personas usan el modelo al mismo tiempo. Si todavía no existe el servidor del modelo, empiece por ejecutar Ollama en un VPS y, si el equipo sólo tiene CPU, consulte cómo se compara Ollama con llama.cpp antes de elegir un runner.
No publique una interfaz de chat sin inicio de sesión en 0.0.0.0
La página de refuerzo de Open WebUI indica que el proyecto está «diseñado para redes privadas y de confianza, como otras infraestructuras autogestionadas, por ejemplo bases de datos, registros de contenedores y servidores de CI», y recomienda colocarlo detrás de una VPN o de un reverse proxy con autenticación. Un proyecto sin ningún inicio de sesión merece como mínimo el mismo tratamiento.
Compruebe qué está escuchando antes de confiar en cualquiera de estos componentes.
sudo ss -lntp | grep -E ':(3000|3080|4173|11434)'Una línea que muestre 127.0.0.1:3000 es lo que necesita. Una línea que muestre 0.0.0.0:3000 significa que el servicio escucha en todas las direcciones, y Docker permite por defecto que cualquier IP de origen externa alcance un puerto publicado. Si una regla de la cadena DOCKER-USER de Docker o el firewall de su proveedor no lo bloquea, la interfaz de chat está en Internet pública. Desde su propia máquina, que curl -sI http://YOUR.VPS.IP:3000 responda a HTTP/1.1 200 OK confirma el problema de forma más directa.
Desactivar el inicio de sesión de Open WebUI con WEBUI_AUTH=False es una configuración para un solo usuario y para una máquina a la que nadie más pueda acceder. Su documentación también indica que sólo funciona en una instalación sin usuarios registrados, por lo que no puede aplicarla a una que ya tenga cuentas.
Patrón uno: vincularse a loopback y acceder mediante SSH. Publique cada puerto en 127.0.0.1 y reenvíe lo que necesite: ssh -N -L 3000:127.0.0.1:3000 you@vps.example.com, y abra http://localhost:3000 en su portátil. No se publica ningún puerto, por lo que no se puede escanear ninguno. Para OrionChat, reenvíe el puerto del modelo en el mismo comando con -L 11434:127.0.0.1:11434 y mantenga Ollama en loopback. Hollama puede acceder directamente a Ollama, pero el mismo reenvío mantiene Ollama fuera de Internet pública, por lo que también es la opción más segura para Hollama. Este patrón sólo es tan seguro como su configuración de SSH, así que combínelo con SSH sólo con claves y un sshd reforzado.
Patrón dos: un reverse proxy que autentica antes de que la aplicación vea la petición. Mantenga la aplicación en loopback, deje que el proxy controle el puerto 443 y coloque el inicio de sesión único delante. Traefik controlado mediante etiquetas de Docker Compose con Authentik como proveedor de identidad proporciona a cada aplicación del equipo un único inicio de sesión y un único certificado. Con Open WebUI detrás de TLS (seguridad de la capa de transporte), configure WEBUI_SESSION_COOKIE_SECURE=true y WEBUI_SESSION_COOKIE_SAME_SITE=strict. Reduzca también JWT_EXPIRES_IN desde su valor predeterminado de cuatro semanas, porque Open WebUI documenta que, sin Redis, cerrar sesión no invalida el token: sigue siendo utilizable hasta que caduca por sí solo.
El patrón dos no soluciona los proyectos que sólo funcionan en el navegador. Un proxy delante de la página no protege el endpoint del modelo, y una petición fetch desde esa página a otro nombre de host no incluye la cookie de sesión. Por eso, el proxy autenticador situado delante de Ollama responde con una redirección a un formulario de inicio de sesión y el chat falla. Encamine el endpoint del modelo bajo el mismo nombre de host que la página o use el patrón uno.
Cuál elegir
Si alguien más va a usarlo, ejecute Open WebUI. Tiene cuentas reales, los usuarios nuevos pasan a una cola de aprobación y sus mantenedores publican recomendaciones de refuerzo que puede seguir. Si necesita LDAP o un panel de administración, ejecute LibreChat, establezca ADMIN_PANEL_SESSION_SECRET si quiere el panel y confirme con docker stats que sus cinco servicios, seis con el panel, además del modelo, caben realmente antes de depender de él. Si lo va a usar una sola persona en un equipo pequeño donde el modelo ya consume la mayor parte de la RAM, sirva Hollama u OrionChat mediante un túnel SSH y deje que el navegador conserve el estado. En un VPS, la opción incorrecta es publicar cualquiera de ellos en 0.0.0.0 sin autenticación delante.
FAQ
¿Es seguro exponer Open WebUI directamente en una IP pública?
Su página de hardening lo describe como software para redes privadas y de confianza, dentro de la misma categoría que una base de datos o un servidor de CI. Tiene cuentas reales, y la primera cuenta se convierte en administrador, mientras las posteriores permanecen pending hasta que se aprueban, por lo que es mucho más seguro que una interfaz sin autenticación. Aun así, colóquelo detrás de un reverse proxy con TLS y, cuando sea posible, con inicio de sesión único. Publique el puerto del contenedor como 127.0.0.1:3000:8080 para que las reglas iptables propias de Docker no puedan abrirlo a Internet sin que usted lo advierta.
¿Qué alternativa a Open WebUI usa menos RAM en un VPS?
Las basadas en navegador, Hollama y OrionChat, porque la aplicación se ejecuta en el cliente. El servidor sólo envía archivos estáticos, y OrionChat ni siquiera necesita un contenedor de aplicación. Open WebUI mantiene en memoria un proceso de Python, una base de datos y, de forma predeterminada, un modelo local de embeddings, documentado en alrededor de 500 MB o más por worker sólo para el modelo de embeddings. Confirme las cifras en su propio equipo con docker stats --no-stream, porque cambian según las funciones que active.
¿Pueden estas interfaces de chat usar un servidor Ollama en otro host?
Open WebUI y LibreChat pueden hacerlo, y la conexión la realiza su servidor, por lo que no se aplica ninguna regla del navegador. Configure OLLAMA_BASE_URL para Open WebUI, o baseURL en un endpoint personalizado para LibreChat. Para vLLM u otro servidor compatible con OpenAI, use OPENAI_API_BASE_URL con la ruta base que documente ese servidor, que en vLLM es /v1, y añada una API key sólo si el servidor la requiere. Hollama también puede apuntar a cualquier dirección, pero la petición se origina en el navegador, por lo que el endpoint también debe ser accesible desde él. OrionChat no puede hacerlo: su dirección de Ollama está codificada como http://localhost:11434, de modo que un Ollama remoto sólo funciona mediante un túnel SSH que reenvíe ese puerto.
¿Por qué mi interfaz de chat en el navegador no puede acceder a Ollama?
Dos causas cubren casi todos los casos. Ollama escucha en 127.0.0.1:11434 de forma predeterminada, por lo que un navegador situado en otra máquina no puede acceder directamente hasta que cambie OLLAMA_HOST o un túnel SSH reenvíe el puerto. Además, Ollama acepta de forma predeterminada peticiones cross-origin desde localhost, 127.0.0.1 y 0.0.0.0, por lo que rechaza una página servida desde su propio dominio con No 'Access-Control-Allow-Origin' header is present on the requested resource hasta que ese origen se incluya en OLLAMA_ORIGINS. Si la página usa HTTPS y el endpoint es HTTP sin cifrar en una dirección IP pública, el navegador bloquea la petición como contenido mixto antes de que Ollama la reciba. Las direcciones de loopback (localhost, cualquier dirección de 127.0.0.0/8 como 127.0.0.2, o [::1]) están exentas. Chrome también exime las peticiones HTTP de red local que usan literales de IP privadas como 192.168.0.1, hostnames .local o targetAddressSpace: "local" después de conceder el permiso de red local; los requisitos CORS de Ollama siguen aplicándose. Configure ambas variables en un override de systemctl edit ollama.service, o reenvíe el puerto mediante SSH para resolver el problema.