Saltar al contenido principal

Docker

Docker es la forma más sencilla de desplegar en un único servidor con una configuración similar a producción.

Para una instalación en un solo servidor accesible desde Internet, empieza por Despliegue remoto privado. Su plantilla Compose no publica puertos de la aplicación, usa de forma predeterminada la imagen main y añade una barrera externa de Cloudflare Access, controles del host, copias de seguridad y límites de contenedores.

Disponibilidad de Work

Work está activado de forma predeterminada en los archivos Compose del repositorio. La imagen incluye la CLI de Docker y Compose monta /var/run/docker.sock, por lo que los contenedores de tareas de Work son hermanos del contenedor Libre WebUI. Aparecen en docker ps en el host.

Un proceso con acceso a ese socket controla el host Docker con privilegios equivalentes a root. Activar Work de forma predeterminada es una decisión deliberada: es una función esencial y no puede funcionar sin acceso al daemon. Por tanto, cada administrador de Libre WebUI es, en la práctica, administrador del host. Planifícalo:

  • Mantén la pila en un host cuyos administradores ya sean de confianza.
  • No expongas el puerto publicado a una red no fiable.
  • Retira el montaje de /var/run/docker.sock cuando Work no sea necesario. La página Work mostrará Entorno de ejecución no disponible.

En Linux, el socket pertenece al grupo docker, no a root, por lo que el usuario sin privilegios de la aplicación necesita el ID de ese grupo. Defínelo una vez:

echo "DOCKER_GID=$(docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
alpine stat -c '%g' /var/run/docker.sock)" >> .env

Léelo mediante un contenedor como se muestra. Un host macOS informa de un valor distinto del que ve el contenedor porque Docker Desktop canaliza el socket mediante una VM. Si el grupo es incorrecto, la página Work indica el problema en lugar de fallar silenciosamente. Consulta Work: espacios de trabajo aislados.

Las vistas previas de Work y el ordenador de Work publican puertos aleatorios solo en una interfaz privada del host. Docker Desktop funciona con los valores predeterminados de Compose: el loopback del host para la vinculación y host.docker.internal para la conexión del backend. Docker Engine nativo no puede alcanzar un servicio que escucha en el loopback del host desde un contenedor hermano. Vincula los puertos a la puerta de enlace no pública de su puente de Docker:

echo "WORK_PREVIEW_BIND=$(docker network inspect bridge \
--format '{{(index .IPAM.Config 0).Gateway}}')" >> .env
echo "WORK_DOCKER_PUBLISHED_HOST=host.docker.internal" >> .env
docker compose up -d --force-recreate libre-webui

Los archivos Compose asignan host.docker.internal a través de host-gateway. No uses nunca WORK_PREVIEW_BIND=0.0.0.0: publicaría puertos de tareas efímeros y sin autenticar en todas las interfaces del host en vez de mantenerlos tras el proxy firmado de Libre WebUI.

Ollama incluido

Ejecuta Libre WebUI y Ollama en una sola pila Compose:

docker compose up -d

Abre http://localhost:8080.

El puerto WebUI se vincula por defecto al loopback del host. Define WEBUI_BIND_ADDRESS=0.0.0.0 solo cuando una LAN de confianza o un proxy inverso del host deban acceder, y restringe el puerto con el cortafuegos.

Ollama permanece privado en la red Compose. Para ponerlo a disposición de aplicaciones del host en loopback, añade la sustitución explícita:

docker compose -f docker-compose.yml -f docker-compose.ollama-host.yml up -d

Define OLLAMA_BIND_ADDRESS únicamente cuando otra máquina deba acceder a Ollama y protege el puerto mediante un cortafuegos y un proxy capaz de autenticar.

GPU NVIDIA

Usa el archivo Compose para GPU cuando Docker tenga acceso al entorno de ejecución de NVIDIA:

docker compose -f docker-compose.gpu.yml up -d

Confirma el acceso a la GPU desde el contenedor Ollama si los modelos siguen ejecutándose en CPU.

Ollama externo

Usa esta opción cuando Ollama ya se ejecute en el host u otro servidor:

docker compose -f docker-compose.external-ollama.yml up -d

Sustituye la URL de Ollama si es necesario:

OLLAMA_BASE_URL=http://192.168.1.10:11434 docker compose -f docker-compose.external-ollama.yml up -d

Work con socket aislado

Los archivos Compose estándar montan el socket Docker dentro del contenedor Libre WebUI para que Work ejecute contenedores de tareas; el montaje concede control del host equivalente a root. Para conservar Work sin entregar el socket a la aplicación web, usa la variante con proxy:

docker compose -f docker-compose.socket-proxy.yml up -d

Un proxy en una red interna conserva /var/run/docker.sock y reenvía únicamente las secciones de API que utiliza Work (contenedores, imágenes, volúmenes, redes, exec e información). Se deniegan los endpoints de Swarm, secretos, configuraciones, compilación y sistema. Libre WebUI accede mediante DOCKER_HOST=tcp://docker-socket-proxy:2375: sin montaje, sin DOCKER_GID, y el terminal interactivo y los diagnósticos funcionan sin cambios. Consulta la documentación de espacios de trabajo para saber qué cubre y qué no cubre este límite.

Persistencia de datos

Libre WebUI almacena los datos del backend en /app/backend/data dentro del contenedor. Los archivos Compose montan esa ruta como volumen con nombre.

La imagen también usa esa ruta cuando se inicia directamente con docker run; los archivos temporales de la comprobación previa de la base permanecen en /app/backend/temp. Monta /app/backend/data siempre que el contenedor pueda volver a crearse.

Para producción, define secretos estables:

JWT_SECRET=replace-with-a-long-random-secret
ENCRYPTION_KEY=replace-with-64-hex-characters

Copia juntos el volumen de datos y la clave de cifrado.

Antes de eliminar un contenedor iniciado directamente desde una imagen antigua, confirma que existe /app/backend/data/.encryption_key o registra el ENCRYPTION_KEY configurado. Las imágenes antiguas podían escribir una clave generada solo en la capa del contenedor; eliminarlo borraba la única clave capaz de descifrar la base persistente.

Si administras un runtime personalizado compatible con Work, sus archivos viven en volúmenes Docker separados y no se incluyen en la copia normal de /app/backend/data.

Acceso público

Los archivos Compose vinculan WebUI a loopback y definen directamente CORS_ORIGIN. Un valor de tu shell o .env no sustituye ese literal. Edita la entrada libre-webui.environment o guarda una sustitución explícita como compose.origin.yml:

services:
libre-webui:
environment:
CORS_ORIGIN: https://your-domain.example
BASE_URL: https://your-domain.example

Aplica la sustitución con el archivo Compose seleccionado:

docker compose -f docker-compose.yml -f compose.origin.yml up -d

Coloca después Libre WebUI detrás de HTTPS mediante un proxy inverso o balanceador. Define WEBUI_BIND_ADDRESS en la interfaz exacta que necesite el proxy; no publiques el puerto en todas las interfaces salvo que el cortafuegos lo exija.

El servidor ya entrega el frontend compilado de forma eficiente: los paquetes con hash bajo /js/ y /assets/ se envían comprimidos con brotli o gzip y con una vida de caché immutable de un año, mientras que index.html y el service worker se marcan como no-cache para que una versión nueva se recoja en la siguiente carga. Un proxy no necesita recomprimir ni almacenar en caché esas rutas; deja pasar Accept-Encoding.

Comandos útiles

docker compose ps
docker compose logs -f libre-webui
docker compose logs -f ollama
docker compose pull
docker compose up -d

Documentación relacionada