DEV Community

Cover image for Reemplacé Docker por Podman para ejecutar LLMs locales (Ollama + DeepSeek)
Afu Tse (Chainiz)
Afu Tse (Chainiz)

Posted on

Reemplacé Docker por Podman para ejecutar LLMs locales (Ollama + DeepSeek)

Durante mucho tiempo, mis experimentos locales con IA siguieron el camino habitual:

"Docker, docker-compose, descargar un modelo, levantar una UI y listo."

Pero en algún punto empecé a querer algo más limpio:

  • Contenedores rootless (sin raíz)
  • Mejor alineación con Linux de nivel enterprise
  • Sin depender de un daemon de Docker corriendo en segundo plano

Ahí fue cuando decidí reconstruir mi stack local de LLMs usando Podman.

Este post documenta el resultado:

"Ollama + Open WebUI + DeepSeek R1 ejecutándose localmente con Podman Compose"


¿Por qué Podman?

Si trabajas en cloud o platform engineering, seguramente ya viste esta tendencia:

  • Podman no usa daemon
  • Corre rootless por defecto
  • Se integra muy bien con systemd
  • Cada vez es más estándar en distribuciones Linux enterprise

Para mí, el objetivo era simple:
ejecutar LLMs locales de la misma forma en que ejecutaría servicios en producción.


El stack

Esto es lo que terminé usando:

  • Ollama → runtime y API de modelos
  • Open WebUI → interfaz tipo chat
  • DeepSeek R1 (1.5B) → liviano pero sorprendentemente capaz
  • Podman Compose → orquestación
  • Volúmenes de Podman → persistencia de datos

Todos los contenedores corren dentro de un solo Podman Pod, lo que significa: una red compartida, comunicación por localhost y cero magia rara de DNS.


Arquitectura

arquitectura


El archivo Compose

El corazón de este setup es el podman-compose.yml:

services:
  ollama:
    image: ollama/ollama:latest
    container_name: ollama-deepseek
    ports:
      - "11434:11434"
    environment:
      - OLLAMA_HOST=0.0.0.0:11434
    volumes:
      - ollama-data:/root/.ollama:Z
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "ollama", "list"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

  open-webui:
    image: ghcr.io/open-webui/open-webui:latest
    container_name: open-webui
    depends_on:
      - ollama
    ports:
      - "3000:8080"
    environment:
      - OLLAMA_BASE_URL=http://ollama:11434
      - WEBUI_SECRET_KEY=${WEBUI_SECRET_KEY:-secret-key-change-me-in-production}
      - ENABLE_SIGNUP=${ENABLE_SIGNUP:-true}
    volumes:
      - open-webui-data:/app/backend/data:Z
    restart: unless-stopped

  model-loader:
    image: ollama/ollama:latest
    container_name: model-loader
    depends_on:
      - ollama
    environment:
      - OLLAMA_HOST=http://ollama:11434
    entrypoint: ["ollama"]
    command: ["pull", "deepseek-r1:1.5b"]
    restart: on-failure

volumes:
  ollama-data:
    driver: local
  open-webui-data:
    driver: local
Enter fullscreen mode Exit fullscreen mode

Codigo fuente

Un detalle pequeño pero importante:
no uso sh -c para el model loader, ya que la imagen de ollama no garantiza un shell, así que llamo al binario directamente.


Ejecución

podman compose up -d
Enter fullscreen mode Exit fullscreen mode

Primer acceso:

  • Abres http://localhost:3000
  • Creas el usuario admin inicial (comportamiento esperado)
  • Empiezas a chatear

Puedes validar Ollama directamente:

curl http://localhost:11434
Enter fullscreen mode Exit fullscreen mode

Qué me gusta de este setup

Después de usarlo un tiempo, hay varias cosas que destacan:

  1. No hay daemon de Docker corriendo
  2. Todo funciona en modo rootless
  3. Separación clara entre runtime, UI y datos
  4. Fácil de convertir en servicios systemd más adelante (Quadlet)

Y lo más importante:
"Esto se siente como infraestructura, no como un demo".


Notas de seguridad (Importante)

Si vas a exponer esto más allá de localhost:

  • Cambia WEBUI_SECRET_KEY
  • Desactiva registros públicos después de crear el primer usuario
  • Considera un reverse proxy

Que sea local no significa que deba ser inseguro.


Conclusión

Ejecutar LLMs localmente no tiene por qué ser desordenado.
Con Podman + Ollama obtienes un setup que se siente:

  1. Limpio
  2. Reproducible
  3. cercano a producción

Si ya usas Podman en tus workloads, este stack encaja perfecto.

Top comments (0)