SSD Nodes Learn Hosting plans →
Guías Matt ConnorPor Matt Connor · Actualizado 2026-09-04

Ollama en Podman rootless en un VPS

Configura Ollama en Podman rootless con usuario dedicado, lingering, Quadlet y SELinux. Mantén el puerto 11434 cerrado y accede mediante un túnel SSH tras reiniciar.

Ejecutar Ollama en Podman rootless en un VPS

Para ejecutar Ollama en Podman rootless en un servidor, deben cumplirse cinco condiciones que un tutorial para equipos de escritorio puede omitir. Un usuario sin privilegios dedicado debe ser el propietario del contenedor. El modo lingering debe estar habilitado para ese usuario, de modo que el contenedor siga ejecutándose después de cerrar la sesión. Un archivo Quadlet debe entregar el contenedor a systemd, para que vuelva a iniciarse después de un reinicio. El directorio de modelos debe tener una etiqueta SELinux en las distribuciones que aplican SELinux. La API debe escuchar sólo en loopback, y se accede a ella mediante un túnel SSH (secure shell).

Ollama es un servidor para modelos de lenguaje grandes (LLM). Almacena los pesos de los modelos en el disco, los carga en memoria y responde a solicitudes HTTP en el puerto 11434. No tiene inicio de sesión, clave de API ni cuentas de usuario, por lo que la red es el único control de acceso disponible. Podman ejecuta contenedores sin un daemon y sin root, de modo que cualquier proceso que escape del contenedor comienza como un usuario normal sin privilegios. Si quiere consultar primero la comparación del runtime, lea cómo difieren Podman y Docker en un VPS. Si prefiere omitir los contenedores por completo, instalar Ollama directamente en un VPS es una opción más corta.

SSD Nodes ofrece Fedora entre sus imágenes, y Fedora incluye Podman y SELinux (security-enhanced Linux) de forma predeterminada. Todos los comandos siguientes se ejecutan en cualquier distribución que incluya Podman 5 o posterior.

Por qué la versión para portátil necesita cambios en un servidor

Fedora Magazine publicó una guía clara sobre esta pila el 5 de agosto de 2026: Ejecución local de Ollama con Podman en Fedora Linux, escrita por Yazan Monshed. Es un buen punto de partida para familiarizarse con las herramientas. También está dirigida a un portátil, y cuatro de sus decisiones se comportan de forma distinta en una máquina con una dirección IP pública.

  • Inicia el contenedor con un `podman run -d` simple. Un contenedor iniciado manualmente no vuelve a iniciarse después de un reinicio porque nunca se configuró que se iniciara.
  • Usa la etiqueta móvil `ollama/ollama`. En un portátil se nota el día en que cambia el comportamiento. En un servidor, la primera señal puede ser un script que dejó de funcionar durante la noche.
  • Publica con `-p 11434:11434`, que enlaza todas las interfaces. Detrás de un router doméstico, el servicio no es accesible desde Internet. En un VPS, se convierte en una API pública de inferencia sin contraseña.
  • Se ejecuta con el usuario con el que inicia sesión. En un servidor, la cuenta propietaria del contenedor no debería ser propietaria de nada más, de modo que una salida del contenedor termine en un directorio personal vacío.

Nada de esto es incorrecto para la máquina a la que se dirige la guía. Cada punto es simplemente una decisión que debe revisarse cuando el equipo es accesible desde cualquier lugar y no hay nadie delante de él.

Cree el usuario sin privilegios y compruebe subuid

Rootless Podman asigna los identificadores de usuario (UID) internos del contenedor a un bloque de identificadores no utilizados en el host. Ese bloque se declara en /etc/subuid y /etc/subgid. Sin este bloque, los contenedores rootless no pueden iniciarse.

sudo dnf install -y podman        # or: sudo apt install -y podman
sudo useradd --create-home --shell /bin/bash --comment "Ollama container owner" ollama
sudo passwd --lock ollama
grep ollama /etc/subuid /etc/subgid

grep debe mostrar dos líneas, una de cada archivo. Cada línea debe indicar un rango de 65536 identificadores:

/etc/subuid:ollama:100000:65536
/etc/subgid:ollama:100000:65536

El número inicial será diferente, y no hay problema. Si grep no muestra nada, useradd no asignó ningún rango y el primer comando podman ejecutado con ese usuario falla de esta forma:

Error: cannot find UID/GID for user ollama: no subuid ranges found for user "ollama" in /etc/subuid

Asigne un rango que ningún otro usuario tenga y, después, indique a Podman que su asignación anterior está obsoleta:

sudo usermod --add-subuids 100000-165535 --add-subgids 100000-165535 ollama
sudo -iu ollama podman system migrate

Bloquear la contraseña impide que alguien inicie sesión directamente como ollama. Para acceder a esa cuenta, use su usuario administrador y sudo -iu ollama.

Habilitar el modo persistente para que el servicio sobreviva al cierre de sesión

La instancia de systemd de un usuario normalmente se inicia al iniciar sesión y se detiene al cerrar sesión, y /run/user/<uid> también se elimina. Todos los contenedores rootless propiedad de ese usuario se detienen en ese mismo momento. El modo persistente mantiene la instancia del usuario en ejecución sin una sesión asociada.

sudo loginctl enable-linger ollama
loginctl show-user ollama --property=Linger

Debe mostrar Linger=yes. Habilítelo antes de crear la unidad, porque el directorio que necesita la unidad, /run/user/<uid>, sólo existe cuando el modo persistente está habilitado.

Queda un paso más que normalmente no se tiene en cuenta. sudo -iu ollama proporciona un shell, pero no un bus de sesión, por lo que systemctl --user falla inmediatamente:

Failed to connect to bus: $DBUS_SESSION_BUS_ADDRESS and $XDG_RUNTIME_DIR not defined

systemd busca el bus del usuario en $XDG_RUNTIME_DIR/bus, y sudo -i no establece esa variable. Establézcala manualmente en cada shell de administración desde el que gestione este servicio:

sudo -iu ollama
export XDG_RUNTIME_DIR=/run/user/$(id -u)
systemctl --user status

Dónde se guardan los blobs de los modelos y cuánto espacio en disco planificar

Ollama escribe los pesos en /root/.ollama/models dentro del contenedor. Monte un directorio del directorio personal del usuario sobre esa ruta y los archivos se guardarán en una ubicación que puede medir: /home/ollama/ollama-data/models. Los blobs se guardan en models/blobs como archivos direccionados por contenido, y models/manifests contiene el índice pequeño que les asigna nombres. Si usa un volumen con nombre, como en el artículo de Fedora Magazine, el mismo árbol se encuentra en /home/ollama/.local/share/containers/storage/volumes/<volume>/_data. En ambos casos, ollama pull y ollama run escriben los pesos en el mismo árbol. lo que diferencia los dos comandos es únicamente si se abre una sesión de chat cuando termina la descarga.

Calcule el espacio en disco antes de descargar nada. Los tamaños de descarga publicados indican el mínimo necesario.

ChartPublished download size per Ollama model tag, ollama.com/library, checked 13 August 2026
The data behind this chart
[
  {
    "label": "gemma3:4b",
    "download_gb": 3.3
  },
  {
    "label": "mistral:7b",
    "download_gb": 4.4
  },
  {
    "label": "qwen3:8b",
    "download_gb": 5.2
  },
  {
    "label": "gemma3:12b",
    "download_gb": 8.1
  },
  {
    "label": "qwen3:14b",
    "download_gb": 9.3
  },
  {
    "label": "gemma3:27b",
    "download_gb": 17
  },
  {
    "label": "qwen3:30b",
    "download_gb": 19
  }
]

Todas las filas de 7 son cifras publicadas en ollama.com/library, no tamaños medidos en un disco. La etiqueta más pequeña de esta lista, gemma3:4b, descarga 3.3 GB. La más grande, qwen3:30b, descarga 19 GB. La propia imagen del contenedor ocupa espacio adicional en el almacenamiento de Podman, por lo que debe comprobar ambos valores con podman system df y df -h /home. Un modelo también necesita aproximadamente el tamaño de su archivo en RAM mientras está cargado, además de espacio para la ventana de contexto. Por eso, un modelo de 19 GB no se ejecutará en un VPS de 16 GB.

Fije la etiqueta de la imagen y use el nombre completo del registro

sudo -iu ollama
export XDG_RUNTIME_DIR=/run/user/$(id -u)
mkdir -p ~/ollama-data ~/.config/containers/systemd
podman pull docker.io/ollama/ollama:0.32.9

Use una etiqueta de versión publicada, 0.32.9 a fecha de agosto de 2026, y no latest. Una etiqueta fijada garantiza que un reinicio a las 04:00 use el mismo binario que probó. Por tanto, cualquier cambio de comportamiento se debe a un cambio que usted realizó. Docker Hub también publica las etiquetas -rc y -rocm para las mismas versiones. Use la etiqueta sin sufijo, salvo que tenga una GPU AMD.

Especifique también el host del registro. En Fedora, un nombre abreviado en una unidad de systemd no tiene un terminal en el que solicitar confirmación. La unidad falla con:

Error: short-name "ollama/ollama" did not resolve to an alias and no unqualified-search registries are defined

Extraer la imagen manualmente antes es opcional, pero resulta útil porque evita que la descarga de varios gigabytes consuma el tiempo de espera de inicio de la unidad.

La unidad Quadlet que sobrevive a un reinicio

Quadlet es el generador de systemd de Podman. Se escribe un archivo .container, systemd lo convierte en un servicio durante el arranque y podman generate systemd deja de ser necesario. Guárdelo como /home/ollama/.config/containers/systemd/ollama.container, con el usuario ollama como propietario.

[Unit]
Description=Ollama API (rootless)
After=network-online.target
Wants=network-online.target

[Container]
Image=docker.io/ollama/ollama:0.32.9
ContainerName=ollama
PublishPort=127.0.0.1:11434:11434
Volume=/home/ollama/ollama-data:/root/.ollama:Z
Environment=OLLAMA_KEEP_ALIVE=30m
Environment=OLLAMA_MAX_LOADED_MODELS=1

[Service]
Restart=always
TimeoutStartSec=900

[Install]
WantedBy=default.target

El nombre del archivo define el nombre del servicio, por lo que ollama.container se convierte en ollama.service.

systemctl --user daemon-reload
systemctl --user start ollama.service
systemctl --user status ollama.service

status debería mostrar active (running). No ejecute systemctl --user enable ollama.service. La unidad no existe como archivo en el disco, por lo que systemd lo rechaza:

Failed to enable unit: Unit file /run/user/1001/systemd/generator/ollama.service is transient or generated.

La sección [Install] ya realiza esa función. Quadlet crea el enlace de inicio durante el arranque mediante daemon-reload. Por eso ese comando no es opcional. TimeoutStartSec=900 cubre un primer inicio que todavía debe descargar la imagen, porque los 90 segundos predeterminados no bastan para una descarga de dos gigabytes y systemd finalizará el inicio como fallido. OLLAMA_KEEP_ALIVE=30m mantiene un modelo en memoria entre peticiones en lugar de descargarlo después de cinco minutos. Las ventajas y desventajas se explican en mantener un modelo de Ollama cargado en memoria. Si algún término de systemd de esta sección no le resulta familiar, cómo funcionan los servicios y temporizadores de systemd en un VPS explica las propias unidades.

Por qué el directorio de modelos devuelve «permiso denegado» con SELinux

En Fedora, RHEL, Rocky y AlmaLinux, SELinux se aplica de forma predeterminada. Un proceso de contenedor se ejecuta en el dominio container_t y un directorio del directorio personal de un usuario tiene la etiqueta user_home_t. La política no permite que uno acceda al otro, por lo que Ollama no puede crear su árbol de modelos y el contenedor termina. getenforce muestra Enforcing en estos sistemas y el rechazo queda registrado:

sudo ausearch -m avc -ts recent

Verá una línea que indica el dominio y la etiqueta del destino:

avc:  denied  { write } for  pid=1842 comm="ollama" name="models" dev="vda1" ino=131077 scontext=system_u:system_r:container_t:s0:c214,c827 tcontext=unconfined_u:object_r:user_home_t:s0 tclass=dir permlisted=0

El :Z al final de la línea Volume= aplica la corrección. Cambia la etiqueta del directorio del host a container_file_t y le asigna una categoría MCS (seguridad mult categoría) privada que sólo lleva este contenedor. La versión en minúsculas, :z, usa una etiqueta compartida. Es la opción adecuada cuando dos contenedores leen el mismo directorio.

Hay una advertencia sobre :Z, porque es destructivo y no muestra avisos. El cambio de etiquetas se aplica de forma recursiva. Si se apunta a /home/ollama, se cambia la etiqueta de todos los archivos de ese directorio personal, lo que impide al usuario acceder a sus claves SSH. Asigne siempre a :Z un subdirectorio dedicado que no contenga nada más. Los volúmenes con nombre no lo necesitan, porque Podman les asigna las etiquetas correctas al crearlos. Para consultar una explicación más amplia, conceptos básicos de SELinux para un servidor explica los contextos y los booleanos. Ubuntu y Debian usan AppArmor; allí :Z no hace nada y dejarlo en la unidad no causa problemas.

Cerrar el puerto 11434 y acceder a la API mediante SSH

PublishPort=127.0.0.1:11434:11434 enlaza el lado del host con la interfaz de loopback. Confírmelo:

ss -ltnp | grep 11434
curl http://127.0.0.1:11434

La salida de ss debe mostrar 127.0.0.1:11434. 0.0.0.0:11434 o *:11434 indica que el puerto está abierto a Internet, y curl debe responder con Ollama is running.

Sea preciso sobre el lado al que aplica el enlace. La dirección de PublishPort es la dirección del host. Dentro del contenedor, Ollama debe seguir escuchando en todas las interfaces, que es el valor predeterminado de la imagen. Establecer Environment=OLLAMA_HOST=127.0.0.1 enlaza Ollama con el loopback propio del contenedor. Podman reenvía el tráfico publicado a la dirección de red del contenedor, por lo que todas las solicitudes se rechazan, incluso desde el host.

Mantener 11434 abierto le expone a dos problemas. Ollama no tiene autenticación, por lo que cualquiera que acceda al puerto puede enumerar sus modelos mediante /api/tags, ejecutar inferencias usando la CPU y el ancho de banda disponible mediante /api/generate, descargar modelos nuevos en el disco y eliminar los existentes. Además, HTTP sin cifrar hacia un puerto remoto envía las solicitudes y las respuestas en texto claro, de modo que cualquier equipo situado en la ruta puede leerlas. Ambos problemas desaparecen si el puerto no sale del equipo.

Desde su estación de trabajo, reenvíe el puerto mediante SSH:

ssh -N -L 11434:127.0.0.1:11434 you@vps.example.com

Ahora http://127.0.0.1:11434 en su portátil corresponde al Ollama del servidor, dentro del cifrado de la sesión SSH. Si su portátil ya ejecuta Ollama, el enlace local falla con bind [127.0.0.1]:11434: Address already in use. Use -L 11435:127.0.0.1:11434 y configure el cliente para que apunte a 11435.

Cuando un cliente de navegador lo necesite, coloque delante un reverse proxy con contraseña. Un bloque de sitio de Caddy tiene cuatro líneas, y caddy hash-password muestra el hash bcrypt que necesita:

ollama.example.com {
  basic_auth {
    you $2a$14$replace_with_the_generated_hash
  }
  reverse_proxy 127.0.0.1:11434
}

Caddy obtiene por sí mismo un certificado mediante TLS (transport layer security), por lo que el tráfico queda cifrado. Pruebe primero el cliente: muchas herramientas que se comunican con Ollama no tienen un campo para una cabecera Authorization y fallarán frente a la autenticación básica con un 401 Unauthorized sin datos. El túnel SSH no tiene ese problema, por lo que es la recomendación predeterminada aquí.

Descargar un modelo y comprobar toda la ruta

podman exec -it ollama ollama pull gemma3:4b
curl -s http://127.0.0.1:11434/api/tags
curl -s http://127.0.0.1:11434/api/generate -d '{"model":"gemma3:4b","prompt":"Reply with the single word: ready","stream":false}'
du -sh ~/ollama-data/models

/api/tags devuelve un JSON que enumera gemma3:4b. /api/generate devuelve un objeto JSON con un campo response, después de una pausa mientras los pesos se cargan desde el disco. du debe mostrar un número cercano al tamaño de descarga publicado. Después, compruebe la parte central de esta guía:

sudo reboot
# reconnect, then:
sudo -iu ollama
export XDG_RUNTIME_DIR=/run/user/$(id -u)
systemctl --user is-active ollama.service

active indica que la solicitud se procesó correctamente, y que la sección [Install] y daemon-reload cumplieron su función. inactive indica que falta uno de los tres elementos.

Modos de fallo y mensajes que verá

El contenedor desaparece después de reiniciar. Compruebe primero loginctl show-user ollama --property=Linger, porque sin Linger=yes la instancia de systemd del usuario nunca se inicia durante el arranque. Si el modo lingering está activado, falta la sección [Install] en el archivo .container, o editó el archivo y no ejecutó systemctl --user daemon-reload.

Error: statfs /home/ollama/ollama-data: no such file or directory. El origen del bind mount debe existir antes de iniciar el contenedor. Podman no crea los directorios del host automáticamente. Ejecute mkdir -p ~/ollama-data como el usuario ollama.

El inicio falla a los 90 segundos. journalctl --user -u ollama.service muestra Start operation timed out. Terminating. porque la descarga de la imagen todavía estaba en curso. Descargue la imagen manualmente o mantenga TimeoutStartSec=900.

El contenedor se inicia y termina. podman logs ollama y sudo ausearch -m avc -ts recent indican conjuntamente si el problema está en la etiqueta de SELinux. Un AVC que menciona container_t y user_home_t significa que falta :Z.

Las solicitudes se rechazan desde el host. curl: (7) Failed to connect to 127.0.0.1 port 11434: Connection refused con el servicio active suele indicar que OLLAMA_HOST se configuró con una dirección de loopback dentro del contenedor. Elimine esa línea.

La generación es muy lenta o el contenedor termina. Sin GPU, la inferencia se ejecuta en la CPU y un modelo grande es lento por naturaleza. Si un contenedor termina durante una solicitud y los registros contienen signal: killed, se trata del mecanismo del kernel que finaliza procesos por falta de memoria. Elija una etiqueta más pequeña del cuadro anterior.

Actualizar una imagen fijada

Fijar una versión significa que las actualizaciones son una tarea que usted controla, no algo que ocurre automáticamente. Edite Image= en ollama.container y, después, vuelva a cargar la configuración y reinicie:

systemctl --user daemon-reload
systemctl --user restart ollama.service
podman exec ollama ollama --version

Los modelos se almacenan en el montaje de enlace, por lo que permanecen intactos al cambiar la imagen. AutoUpdate=registry de la sección [Container] existe para quienes ejecutan una etiqueta móvil y no sirve junto a una etiqueta de versión fija, porque el contenido de esa etiqueta nunca cambia. Haga una copia de seguridad de /home/ollama/ollama-data/models/manifests y del archivo .container, e ignore los blobs: ocupan mucho espacio y ollama pull los descarga de nuevo en un equipo nuevo.

FAQ

¿Por qué se detiene mi contenedor rootless de Podman cuando cierro la sesión?

La instancia de systemd de un usuario y su directorio /run/user/<uid> se desmontan cuando termina la última sesión de ese usuario, y todos los contenedores rootless se detienen con ellos. Ejecute sudo loginctl enable-linger ollama y confirme que loginctl show-user ollama --property=Linger muestra Linger=yes. Habilite el modo lingering antes de crear la unidad Quadlet, porque el directorio de ejecución que necesita la unidad sólo existe cuando el modo lingering está activo.

¿Necesito etiquetas de SELinux en el directorio de modelos de Ollama?

En Fedora, RHEL, Rocky y AlmaLinux, sí, si monta un directorio del host mediante bind mount. El contenedor se ejecuta en el dominio container_t y un directorio dentro de un directorio personal tiene la etiqueta user_home_t, por lo que se deniega la escritura y Ollama se cierra. Añada :Z a la línea Volume= y asígnele un subdirectorio dedicado, porque el cambio recursivo de etiquetas afecta a todo el contenido y apuntar :Z a un directorio personal completo impide el acceso a las claves SSH de ese usuario. Podman etiqueta correctamente los volúmenes con nombre y no necesitan nada más.

¿Cuánto espacio de disco necesita un modelo de Ollama?

Empiece por el tamaño de descarga publicado en ollama.com/library, que va desde 3.3 GB para gemma3:4b hasta 19 GB para qwen3:30b. Añada la imagen de Podman y deje espacio libre adicional, porque un segundo modelo no reemplaza al primero en el disco. Compruebe df -h /home antes de descargarlo y du -sh ~/ollama-data/models después. Planifique la RAM del mismo modo: un modelo necesita aproximadamente el tamaño de su archivo en memoria mientras está cargado, además de la ventana de contexto.

¿Es seguro exponer el puerto 11434 en un VPS?

No. Ollama se distribuye sin ningún tipo de autenticación, por lo que cualquiera que alcance el puerto puede enumerar sus modelos, eliminarlos, descargar otros en el disco y ejecutar inferencias usando la CPU y el límite de ancho de banda. El protocolo HTTP sin cifrar a través de Internet también envía cada solicitud y respuesta en texto claro. Enlace el lado del host a 127.0.0.1 con PublishPort=127.0.0.1:11434:11434, confirme el resultado con ss -ltnp | grep 11434 y acceda mediante un túnel SSH o un reverse proxy que requiera una contraseña.