Docker y Podman son dos motores de contenedores: programas que empaquetan una aplicación junto con todo lo que necesita para funcionar y la ejecutan aislada del resto del sistema. Docker es el estándar de facto desde 2013; Podman, impulsado por Red Hat, hace prácticamente lo mismo con una diferencia de fondo: no necesita ningún servicio central corriendo como root. Ambos trabajan con las mismas imágenes compatibles con el estándar OCI, así que en la mayoría de los casos basta con escribir podman donde escribías docker.
Este artículo parte de lo básico —qué es un contenedor y en qué se diferencia de una máquina virtual— y llega hasta el criterio práctico: cómo funciona docker run, qué aporta realmente Podman, en qué se diferencian y cuál conviene en cada escenario.

Qué es un contenedor (y qué no es)
Un contenedor es un proceso normal de Linux al que se le han puesto límites. No es una máquina virtual pequeña, ni un sistema operativo dentro de otro. Es, literalmente, un proceso —o un grupo de procesos— que el núcleo mantiene aislado del resto mediante dos mecanismos que existen desde hace años:
- Namespaces: lo que el proceso puede ver. Hay un espacio de nombres para los procesos, otro para la red, otro para el sistema de ficheros, otro para los usuarios, y así hasta una docena. Un contenedor vive en su propio juego de namespaces, de modo que ve sus procesos como si fueran los únicos y tiene su propia pila de red.
- cgroups (control groups): lo que el proceso puede consumir. Limitan y contabilizan CPU, memoria, entrada/salida de disco y número de procesos. Son los que evitan que un contenedor se coma el servidor entero.
La consecuencia más importante se deduce de ahí: todos los contenedores de una máquina comparten el mismo núcleo. Eso los hace ligerísimos, porque no hay que arrancar ningún sistema operativo, pero también significa que el aislamiento es de proceso, no de hardware. El detalle está bien documentado en la propia documentación del núcleo Linux y en la guía de seguridad de contenedores del NIST (SP 800-190), que dedica capítulos enteros a las diferencias de modelo de amenaza entre contenedores y máquinas virtuales.
Para no confundir el envoltorio con el contenido, conviene tener claros cuatro términos que se usan todo el rato:
- Imagen: la plantilla inmutable desde la que se arranca un contenedor. Un paquete con el sistema de ficheros y las instrucciones de arranque.
- Contenedor: una instancia en ejecución de una imagen. Como la clase y el objeto en programación: una imagen puede dar muchos contenedores.
- Registro: el almacén donde se publican y descargan las imágenes (Docker Hub, GitHub Container Registry, un registro privado…).
- Runtime: la pieza de bajo nivel que habla con el núcleo para crear el contenedor (
runc,crun). Ni Docker ni Podman lo escriben todo: se apoyan en estos componentes.
Contenedor frente a máquina virtual
La comparación con una VM es la pregunta más frecuente, y la respuesta corta es que resuelven problemas distintos. Una máquina virtual virtualiza hardware y arranca un sistema operativo completo invitado sobre un hipervisor. Un contenedor no arranca ningún sistema: reutiliza el del anfitrión y solo aísla el proceso.
| Contenedor | Máquina virtual | |
|---|---|---|
| Qué se virtualiza | Procesos aislados con namespaces y cgroups | Hardware completo sobre un hipervisor |
| Núcleo | El del anfitrión, compartido | Uno propio por cada VM invitada |
| Arranque | Milisegundos | Decenas de segundos |
| Peso típico | De pocos MB a unos cientos | Varios GB por VM |
| Densidad | Decenas o cientos por servidor | Unas pocas por servidor |
| Aislamiento | Más débil: se comparte el núcleo | Más fuerte: frontera de hardware |
| Sistemas operativos | Los que compartan el mismo tipo de núcleo | Cualquiera, incluido otro SO distinto |
| Uso habitual | Microservicios, CI/CD, entornos de desarrollo | Cargas que exigen aislamiento fuerte o SO distintos |
Dicho de otro modo: una VM aísla sistemas y un contenedor aísla aplicaciones. Por eso lo normal no es elegir uno u otro, sino combinar ambos: contenedores corriendo dentro de máquinas virtuales, que es exactamente lo que hace cualquier clúster de Kubernetes en la nube. La virtualización de hardware no es nueva ni un accidente: es un capítulo más de la historia de los sistemas operativos.
Imágenes, capas y el estándar OCI
Una imagen de contenedor no es un bloque monolítico, sino una pila de capas de solo lectura. Cada instrucción de un Dockerfile que modifica el sistema de ficheros genera una capa nueva, y las capas se comparten entre imágenes. Si dos imágenes parten de la misma base, esa base se descarga y se guarda una sola vez. Al arrancar un contenedor se añade por encima una capa fina de escritura: lo que se modifica vive ahí y desaparece cuando el contenedor se elimina, salvo que se use un volumen.
El formato de esas imágenes no es propiedad de nadie en concreto. Lo define la Open Container Initiative (OCI), un proyecto bajo la Linux Foundation que fija dos especificaciones: la de imagen y la de runtime. Docker, Podman y los registros de todas las nubes hablan ese mismo idioma. Es la razón por la que puedes construir una imagen con una herramienta y ejecutarla con otra sin tocar nada.
Docker: motor, imágenes y registros
Docker es la empresa y el conjunto de herramientas que popularizó los contenedores a partir de 2013. Cuando alguien dice «Docker» puede estar hablando de tres cosas distintas, y conviene separarlas desde el principio.
El motor y el demonio
El Docker Engine es el motor: el servicio (dockerd) que escucha órdenes, gestiona imágenes, redes y volúmenes y lanza contenedores. La arquitectura clásica de Docker es cliente-servidor: el comando docker que escribes en la terminal no hace el trabajo, solo envía una petición al demonio a través de un socket Unix —por defecto /var/run/docker.sock— y muestra la respuesta. La visión general de la documentación oficial describe esa arquitectura pieza a pieza.
Esa centralización es cómoda, pero tiene una implicación de seguridad que conviene entender: el demonio corre como root y quien puede hablar con su socket puede, en la práctica, obtener privilegios de root en el anfitrión. Añadir un usuario al grupo docker es una decisión de seguridad de primer orden, no un detalle administrativo. El NIST lo recoge expresamente entre los riesgos del modelo de Docker.
Imagen, contenedor y registro en la práctica
El flujo de trabajo diario tiene tres pasos que se repiten:
# 1. Buscar y descargar una imagen del registro
docker pull nginx:1.27-alpine
# 2. Listar las imágenes que ya tengo en local
docker images
# 3. Arrancar un contenedor a partir de esa imagen
docker run -d --name web -p 8080:80 nginx:1.27-alpine
El registro es la pieza que hace que esto sea portable. Docker Hub es el más conocido y viene configurado por defecto, pero no es el único: GitHub Container Registry, Amazon ECR, Google Artifact Registry y cualquier registro privado compatible con OCI funcionan igual. Un registro guarda imágenes con nombre y etiqueta (tag); la etiqueta latest es solo la que se usa cuando no especificas ninguna, no significa «la más nueva» ni «la más estable». El concepto de registro está explicado con más detalle en la documentación de Docker.
Docker Hub aplica límites de descarga a las cuentas gratuitas y anónimas. En entornos serios eso suele resolverse de dos maneras: autenticándose o, mejor, con un registro propio que actúe de caché interna. Es un detalle de operación que aparece antes de lo que parece.
docker run: cómo se arranca un contenedor
docker run hace dos cosas en una: crea un contenedor a partir de una imagen y lo arranca. Su estructura es siempre la misma:
docker run [OPCIONES] IMAGEN[:ETIQUETA] [COMANDO] [ARGUMENTOS...]
Las tres partes importan. Las opciones van antes del nombre de la imagen y describen cómo quieres el contenedor (puertos, variables, volúmenes, nombre…). La imagen puede llevar etiqueta o un digest para fijar una versión exacta. Y el comando final es opcional: si lo escribes, sustituye al que la imagen tenía definido por defecto (CMD o ENTRYPOINT). La referencia oficial de docker run es la fuente primaria para consultar cualquier opción que no aparezca aquí.
# Ejecuta la imagen tal cual, con su comando por defecto
docker run alpine
# Sobrescribe el comando por defecto: aquí, consulta la IP del contenedor
docker run --rm alpine ip addr
Las opciones que usarás el 90 % del tiempo
| Opción | Qué hace |
|---|---|
-d |
Ejecuta en segundo plano (detached) y libera la terminal. |
-it |
Sesión interactiva con terminal. Para abrir una shell dentro del contenedor. |
--name |
Asigna un nombre. Es único: no puede repetirse ni aunque el contenedor esté parado. |
--rm |
Elimina el contenedor al terminar. Evita acumular ejecuciones muertas. |
-p 8080:80 |
Publica el puerto 80 del contenedor en el 8080 del anfitrión. |
-P |
Publica todos los puertos expuestos por la imagen en puertos aleatorios. |
-e CLAVE=valor |
Define una variable de entorno dentro del contenedor. |
-v nombre:/ruta |
Monta un volumen (persistente) o un directorio del anfitrión (bind mount). |
--network |
Conecta el contenedor a una red concreta en lugar de la red por defecto. |
--restart |
Política de reinicio: no, on-failure, always, unless-stopped. |
--entrypoint |
Sustituye el punto de entrada de la imagen. |
-m, --cpus |
Limitan memoria y CPU del contenedor. |
Un comando real, línea a línea
Vamos con un ejemplo concreto de un servidor web con su base de datos, que es donde se ven casi todas las opciones juntas:
docker network create tienda
docker run -d
--name tienda-db
--restart unless-stopped
--network tienda
-e POSTGRES_PASSWORD=secreto
-e POSTGRES_DB=tienda
-v datos-db:/var/lib/postgresql/data
postgres:16-alpine
docker run -d
--name tienda-web
--network tienda
-p 8080:80
-e DB_HOST=tienda-db
miweb:1.4
En el primer comando, -d deja el contenedor en segundo plano; --name le da un nombre legible; --restart unless-stopped hace que vuelva a levantarse si el servidor se reinicia; las dos -e pasan credenciales y nombre de la base como variables de entorno; y -v datos-db:/var/lib/postgresql/data monta un volumen con nombre, de modo que los datos sobreviven a la desaparición del contenedor. Ese último punto es el que más se olvida en las pruebas: los datos de un contenedor sin volumen son volátiles.
En el segundo, -p 8080:80 publica el servicio, y --network tienda lo mete en la misma red que la base de datos, de forma que puede resolverla por su nombre (tienda-db) sin exponer nada a Internet. Los contenedores de una red definida por el usuario se ven entre sí por nombre; los de la red por defecto, no. Publicar un puerto no es más que redirigir tráfico TCP o UDP de una máquina a otra, con la misma lógica que se estudia en cómo funciona TCP/IP.
Para comprobar cómo va todo, los dos comandos de siempre son docker ps (solo los que corren) y docker ps -a (también los parados). Sus columnas —ID, imagen, comando, estado, puertos y nombre— resumen el ciclo de vida completo. Y para entrar en un contenedor que ya está corriendo se usa docker exec:
docker exec -it tienda-web sh
docker logs -f tienda-web
docker stop tienda-web && docker rm tienda-web
Un matiz que ahorra confusión: docker exec abre un proceso nuevo dentro de un contenedor que ya funciona, mientras que docker run crea uno nuevo desde cero. Si el contenedor murió, exec no sirve: hay que mirar sus logs y arrancar otro.
Podman: el mismo contenedor sin demonio
Podman («Pod Manager») nació en Red Hat con una idea sencilla de enunciar y complicada de ejecutar: hacer todo lo que hace Docker, pero sin un servicio central. En lugar de un demonio que atiende peticiones, cada orden que escribes lanza un proceso que crea el contenedor y termina. Podman es hoy el motor de contenedores que Red Hat incluye y soporta en RHEL, y el que usa por debajo OpenShift. Su comportamiento y sus comandos están documentados en la documentación oficial de Podman.
Daemonless: por qué importa
La etiqueta que resume la filosofía de Podman es daemonless: sin demonio. Cuando ejecutas podman run, no hay ningún servicio escuchando en un socket permanente al que haya que enviar la orden. El contenedor es hijo directo de tu sesión (o queda gestionado por systemd), y no hay una pieza central que, si cae, se lleve por delante todo lo que corre en la máquina.
La diferencia no es solo de robustez. Un demonio central como el de Docker es un punto único de fallo y, sobre todo, un punto único de privilegio: comprometerlo equivale a comprometer el anfitrión. Sin demonio, esa superficie desaparece.
Rootless: contenedores sin ser root
La segunda ventaja va de la mano: Podman está pensado para funcionar sin privilegios. Un usuario normal puede crear y ejecutar contenedores, que se guardan en su propio directorio (~/.local/share/containers) y no se mezclan con los de otros usuarios. Un podman images ejecutado como usuario corriente solo muestra las suyas.
Por debajo se usan user namespaces: el usuario sin privilegios se mapea a un rango de identificadores subordinados dentro del contenedor, de modo que dentro puede verse como root sin serlo fuera. Es una capa de aislamiento más, y encaja con el principio de mínimo privilegio que se aplica en cualquier diseño de seguridad, el mismo que ordena los modelos de control de acceso basado en roles.
Pods: el guiño a Kubernetes
El nombre de Podman no es casual. Además de contenedores sueltos, puede ejecutar pods: la misma unidad que usa Kubernetes. Un pod es un grupo de uno o más contenedores que comparten red, direcciones IP y espacio de nombres, de manera que se comunican entre sí por localhost como si fueran el mismo equipo. El patrón habitual es un contenedor principal acompañado de contenedores auxiliares (sidecars) que le hacen tareas de apoyo. La creación de pods está detallada en la referencia de podman pod create.
podman pod create --name webapp -p 8080:80
podman run -d --pod webapp --name app miweb:1.4
podman run -d --pod webapp --name cache redis:7-alpine
podman pod ps
Esa compatibilidad conceptual tiene una ventaja práctica: lo que montas en local con pods de Podman se traduce casi directamente a manifiestos de Kubernetes, sin aprender dos modelos mentales distintos.
El ecosistema alrededor de Podman
Podman no viene solo. Red Hat lo acompaña de varias herramientas que cubren lo que en Docker hace el propio demonio:
- Buildah: construye imágenes OCI, con o sin
Dockerfile, y permite montar el sistema de ficheros de un contenedor para retocarlo. - Skopeo: inspecciona, copia y firma imágenes entre registros sin necesidad de descargarlas al equipo.
- Quadlet: genera unidades de systemd a partir de ficheros de configuración, para que un contenedor arranque y se reinicie como cualquier servicio del sistema.
- podman compose: permite usar ficheros
compose.yamlcon Podman, apoyándose en un proveedor externo.
La integración con systemd es uno de sus puntos fuertes. Allí donde en Docker se depende del --restart del demonio, en Podman el contenedor puede declararse como un servicio más, con dependencias, After=, WantedBy= y activación por socket. Y donde Docker tiene Docker Compose y Swarm, Podman apunta directamente a Kubernetes, que es el estándar de orquestación que usan las nubes.
Docker y Podman: diferencias reales
Si los dos ejecutan las mismas imágenes y comparten casi toda la sintaxis, ¿dónde está la diferencia? En la arquitectura, el modelo de privilegios y el ecosistema:
| Docker | Podman | |
|---|---|---|
| Arquitectura | Cliente-servidor con demonio (dockerd) |
Sin demonio: un proceso por orden |
| Privilegios | El demonio corre como root; existe modo rootless opcional |
Rootless por defecto y de primera clase |
| Socket | /var/run/docker.sock |
$XDG_RUNTIME_DIR/podman/podman.sock, por usuario |
| Imágenes | OCI y Docker | OCI (las mismas) |
| Línea de comandos | docker … |
podman …, compatible |
| Pods | No: solo contenedores sueltos | Sí, pods equivalentes a los de Kubernetes |
| Orquestación | Docker Compose y Swarm | Compose (vía podman compose) y Kubernetes |
| Construcción | Docker Build / BuildKit | podman build y Buildah |
| Systemd | Gestión propia mediante reinicios | Integración nativa con systemd (Quadlet) |
| Escritorio | Docker Desktop | Podman Desktop |
| Licencia de escritorio | Suscripción de pago para empresas grandes | Sin coste |
La línea de comandos es compatible de forma intencionada. Muchos de los comandos son idénticos (run, ps, images, exec, logs, stop, rm, build, pull, push), y resulta habitual encontrar guías que usan un alias —alias docker=podman— para no cambiar la memoria muscular. Lo que no es idéntico es lo que depende del demonio: quien programa contra la API de Docker por su socket probablemente necesite el servicio de Podman activado para exponer un socket compatible.
¿Es Podman el sucesor de Docker?
Ni sucesor ni clon exacto. Podman ha ganado terreno donde el aislamiento y los privilegios pesan más que la comodidad: servidores Linux gestionados por systemd, entornos donde no se quiere un servicio root permanente y plataformas basadas en Kubernetes. Docker conserva la ventaja de la adopción: es el nombre que todo el mundo conoce, tiene el ecosistema más amplio, Docker Desktop es la vía más cómoda en Windows y macOS, y sigue siendo el estándar de facto en muchos flujos de desarrollo.
Conviene separar además dos cosas que se confunden a menudo: el Docker Engine es software libre y gratuito; lo que tiene suscripción en determinados casos es Docker Desktop, que es gratis para uso personal y pequeña empresa, pero requiere pago en empresas grandes. En Linux, el motor se instala sin coste. Esa distinción explica por qué algunas organizaciones migran a Podman sin que les moleste técnicamente Docker. Los criterios de licencia están en la página de suscripciones de Docker.
Cuándo usar cada uno
La pregunta útil no es cuál es mejor, sino en qué contexto encaja cada uno.
Docker encaja bien cuando…
- Trabajas en Windows o macOS y quieres la vía con menos fricción: Docker Desktop encapsula la máquina virtual y la gestión por ti. En Windows se apoya en el subsistema Linux, así que conocer qué es WSL2 ayuda a entender qué hay debajo.
- Tu equipo ya tiene flujos con
Dockerfile, Compose y la API de Docker, y cambiarlos no aporta nada. - Necesitas el mayor ecosistema posible de imágenes, extensiones y herramientas de terceros.
- Vas a usar Docker Swarm como orquestador sencillo, con la estructura que ya conoces.
Podman encaja bien cuando…
- Administras servidores Linux y quieres contenedores gestionados como servicios de systemd, sin demonio permanente.
- La seguridad y el mínimo privilegio son un requisito: contenedores rootless por defecto y sin un socket que otorgue
roota quien lo alcance. - Vas hacia Kubernetes: los pods de Podman son el mismo concepto y la curva es menor.
- Quieres evitar costes de licencia de escritorio en una organización grande, o dependes de entornos Red Hat.
En muchas máquinas conviven sin problema, porque usan rutas y almacenes distintos. La regla práctica es elegir uno como principal para no duplicar imágenes y no liarse con dos almacenes locales; el otro puede quedarse para pruebas puntuales.
Buenas prácticas que sirven para los dos
Las decisiones que de verdad marcan la diferencia en producción son independientes del motor que elijas:
- Fija versiones, no uses
latest. Una etiqueta concreta (nginx:1.27-alpine) o, mejor, un digest hacen que la misma imagen sea siempre la misma. Conlatest, dos despliegues del mismo código pueden ejecutar versiones distintas. - Imágenes mínimas y por etapas. Parte de bases pequeñas (por ejemplo, variantes alpine o slim) y usa construcción en varias etapas para no arrastrar compiladores ni ficheros innecesarios a la imagen final. Menos superficie es menos vulnerabilidades y descargas más rápidas.
- Nunca metas secretos en la imagen. Ni contraseñas ni claves en un
Dockerfile: quedan grabadas en las capas y cualquiera que descargue la imagen las puede leer. Los secretos se inyectan en tiempo de ejecución con variables de entorno, ficheros montados o un gestor de secretos. - No ejecutes como
rootdentro del contenedor. Declara un usuario sin privilegios con la instrucciónUSER. Si además el motor es rootless, se suman las dos capas de protección. - Limita los recursos. CPU y memoria acotadas evitan que un contenedor descontrolado arrastre al anfitrión y a sus vecinos.
- No montes el socket del motor dentro de un contenedor salvo que sepas exactamente lo que haces. Quien lo controle desde dentro pasa a tener el mismo poder que el propio motor sobre el anfitrión.
- Persiste solo lo que deba persistir. Bases de datos y datos de usuario, en volúmenes con nombre; el resto, en la capa efímera del contenedor. Y ten un plan de copia de seguridad para esos volúmenes, porque el contenedor no protege de un borrado accidental.
- Escribe los registros en la salida estándar. Un contenedor debe registrar en
stdout/stderry dejar que el motor o la plataforma los recoja, en lugar de escribir ficheros dentro que se pierden con el contenedor. - Escanea y firma las imágenes. Analizarlas en busca de vulnerabilidades conocidas y verificar su procedencia antes de desplegar cierra el hueco entre «funciona» y «es seguro».
- Un proceso por contenedor. Es lo que hace que escalar, reiniciar y depurar sean operaciones predecibles.
Conclusión
Docker y Podman resuelven el mismo problema —empaquetar y ejecutar aplicaciones de forma aislada y portable— con dos filosofías distintas. Docker apuesta por un servicio central cómodo y con el mayor ecosistema; Podman apuesta por prescindir de él, ejecutar sin privilegios y hablar el idioma de Kubernetes. Como ambos usan el mismo formato de imagen OCI, la decisión no es irreversible: el contenido que construyes vale igual en los dos.
Lo que de verdad importa no es el logo de la herramienta, sino entender el modelo de aislamiento, fijar versiones, no meter secretos en las imágenes y limitar privilegios y recursos. Con esas bases, cambiar de motor es una tarde de trabajo, no una migración de meses.
Preguntas frecuentes
¿Se pueden ejecutar en Podman las mismas imágenes que en Docker?
Sí. Podman trabaja con imágenes OCI, el mismo formato que usa Docker, por lo que las imágenes de Docker Hub funcionan sin conversión. La línea de comandos también es compatible en su mayor parte, lo que hace que la transición sea casi inmediata.
¿Podman es el sucesor de Docker?
Es más exacto decir que es una alternativa consolidada, no un reemplazo universal. Podman ha ganado peso en servidores Linux y en entornos Red Hat por su modelo sin demonio y rootless, mientras que Docker conserva una adopción mayor y un ecosistema más amplio. Los dos siguen evolucionando.
¿Docker deja de ser gratis?
El Docker Engine sigue siendo software libre y gratuito. Lo que tiene suscripción es Docker Desktop, que es gratis para uso personal y pequeñas empresas y requiere pago en empresas grandes. Si te preocupa el coste en Linux, el motor no lo tiene.
¿Un contenedor es lo mismo que una máquina virtual?
No. Una máquina virtual arranca un sistema operativo completo sobre hardware virtualizado, mientras que un contenedor es un proceso aislado que comparte el núcleo del anfitrión. Los contenedores son mucho más ligeros y arrancan en milisegundos; las máquinas virtuales ofrecen un aislamiento más fuerte.
¿Puedo usar Docker y Podman en la misma máquina?
Sí, aunque conviene designar uno como principal para no duplicar imágenes ni crear almacenes locales paralelos. Un uso habitual es tener Podman en los servidores y Docker Desktop en el equipo de desarrollo, o al revés, y compartir las imágenes a través de un registro.
¿Qué es un pod de Podman?
Es un grupo de contenedores que comparten red y espacio de nombres, exactamente igual que un pod de Kubernetes. Se usa para agrupar contenedores que deben ir juntos —por ejemplo, una aplicación y su sidecar— y poder comunicarlos por localhost.