En esta lección abriremos el capó para entender cómo funciona Docker por dentro. Hasta ahora hemos hablado de imágenes y contenedores a alto nivel; ahora veremos qué piezas trabajan entre bastidores cada vez que escribes un comando como docker run. Conocerás la arquitectura cliente-servidor sobre la que se construye Docker, el papel del daemon, de la CLI y de la API REST, los distintos objetos que gestiona (imágenes, contenedores, redes y volúmenes) y el rol de componentes de bajo nivel como containerd y runc. Comprender esta arquitectura te permitirá razonar sobre lo que ocurre realmente y diagnosticar problemas con criterio.

Una Arquitectura Cliente-Servidor

Docker no es un único programa, sino un sistema con dos partes principales que se comunican entre sí:

  • El cliente (la herramienta docker que escribes en la terminal): recibe tus comandos y los traduce en peticiones.
  • El servidor (el daemon de Docker): recibe esas peticiones y hace el trabajo de verdad: construir imágenes, crear contenedores, gestionar redes, etc.

Esta separación se llama arquitectura cliente-servidor. Lo interesante es que el cliente y el servidor no tienen por qué estar en la misma máquina: puedes controlar un Docker que se ejecuta en un servidor remoto desde el cliente de tu portátil, porque se comunican a través de una API.

Componente Qué es Su responsabilidad
Docker CLI La herramienta de línea de comandos docker Traducir tus comandos en peticiones a la API
Docker daemon El proceso servidor (dockerd) Ejecutar el trabajo: imágenes, contenedores…
API REST El "idioma" entre cliente y daemon Permitir la comunicación entre ambos
Registro Almacén de imágenes (p. ej. Docker Hub) Guardar y servir imágenes

El Docker Daemon (dockerd)

El daemon es el corazón de Docker. Es un proceso que se ejecuta en segundo plano de forma permanente (de ahí el sufijo "d" de daemon, que en sistemas Unix designa a un servicio en segundo plano) y se encarga de todo el trabajo pesado.

Responsabilidades del daemon:

  • Construir imágenes a partir de un Dockerfile.
  • Crear, iniciar, detener y eliminar contenedores.
  • Gestionar las redes y los volúmenes.
  • Descargar (pull) y subir (push) imágenes desde y hacia los registros.
  • Mantener el estado de todos los objetos Docker.

Cuando instalaste Docker Desktop, el daemon arrancó automáticamente. En Linux, lo gestiona normalmente el sistema de servicios (por ejemplo, systemctl start docker). Si el daemon no está en marcha, ningún comando de Docker funcionará.

La Docker CLI

La CLI (Command Line Interface) es la herramienta docker que usas en la terminal. Es solo un "mando a distancia": no ejecuta contenedores por sí misma, sino que traduce tus comandos en peticiones HTTP que envía al daemon a través de la API.

Por ejemplo, cuando escribes:

docker run nginx
  • La CLI interpreta tu intención: "crear y arrancar un contenedor a partir de la imagen nginx".
  • La convierte en una o varias peticiones a la API REST del daemon.
  • El daemon recibe la petición, descarga la imagen si hace falta, crea el contenedor y lo arranca.
  • El daemon responde a la CLI, que te muestra el resultado en pantalla.

La API REST

La API REST es el conjunto de reglas que permite que la CLI (o cualquier otro programa) hable con el daemon. Es la pieza que hace posible la arquitectura cliente-servidor.

  • En un sistema local, la comunicación suele producirse a través de un socket (en Linux, /var/run/docker.sock).
  • También puede exponerse por red (con la debida seguridad) para controlar Docker de forma remota.
  • Como es una API estándar, no estás obligado a usar la CLI oficial: existen interfaces gráficas y librerías para muchos lenguajes que hablan directamente con esta API.

Esto explica por qué herramientas externas (paneles de control, plugins de IDE, sistemas de orquestación) pueden gestionar Docker: todas usan la misma API.

Los Objetos de Docker

El daemon gestiona varios tipos de objetos. Estos son los cuatro fundamentales que usarás a diario:

Objeto Qué es Persistencia
Imagen Plantilla de solo lectura para crear contenedores Persistente (hasta que la borres)
Contenedor Instancia en ejecución de una imagen Efímero por naturaleza
Red Permite la comunicación entre contenedores y con el exterior Persistente (hasta que la borres)
Volumen Mecanismo para almacenar datos fuera del contenedor Persistente, independiente del contenedor
  • Imágenes: las plantillas inmutables a partir de las cuales se crean los contenedores.
  • Contenedores: las instancias en ejecución. Son efímeros: si eliminas un contenedor, se pierde su estado interno (salvo lo que guardes en volúmenes).
  • Redes: permiten que los contenedores se comuniquen entre sí y con el mundo exterior de forma controlada.
  • Volúmenes: la forma recomendada de persistir datos (por ejemplo, los de una base de datos) más allá de la vida de un contenedor.

Profundizaremos en imágenes, redes y volúmenes en módulos posteriores; por ahora basta con saber que el daemon es quien los gestiona todos.

containerd y runc: las Capas de Bajo Nivel

Docker no ejecuta los contenedores "directamente". Por debajo del daemon hay componentes especializados que se reparten el trabajo. No necesitas interactuar con ellos a diario, pero conocer su existencia ayuda a entender el conjunto.

Componente Nivel Responsabilidad principal
dockerd Alto Recibe peticiones de la API y coordina todo
containerd Intermedio Gestiona el ciclo de vida de los contenedores e imágenes
runc Bajo Crea realmente el contenedor usando las características del kernel
  • containerd: un runtime de contenedores que se sitúa entre el daemon y runc. Se encarga del ciclo de vida (arrancar, parar, pausar), de gestionar las imágenes y del almacenamiento. Es un estándar de la industria, tanto que otras plataformas (como Kubernetes) también lo utilizan.
  • runc: el componente de más bajo nivel. Es quien, finalmente, crea el contenedor usando las funcionalidades del kernel de Linux (namespaces para el aislamiento y cgroups para limitar recursos). Cumple el estándar OCI (Open Container Initiative).

La idea clave es la separación por capas: cada componente hace una cosa concreta, lo que hace el sistema más modular, mantenible e interoperable.

El Flujo Completo: ¿Qué Pasa al Ejecutar docker run?

Veamos paso a paso qué ocurre entre bastidores cuando ejecutas un comando tan sencillo como docker run nginx. Este recorrido conecta todas las piezas que hemos visto.

  [Tú escribes en la terminal]
            |
            v
   docker run nginx          (1) La CLI interpreta el comando
            |
            v
   API REST  --------------> (2) Envía la petición al daemon
            |
            v
      dockerd                (3) El daemon recibe la petición
            |
   ¿Existe la imagen localmente?
       |            |
      Sí           No -----> (4) Descarga la imagen del registro (Docker Hub)
       |            |
       v            v
     containerd             (5) Prepara el ciclo de vida del contenedor
            |
            v
       runc                  (6) Crea el contenedor con namespaces y cgroups
            |
            v
  [Contenedor en ejecución]  (7) Nginx arranca dentro del contenedor
            |
            v
   API REST  --------------> (8) El daemon informa del resultado a la CLI
            |
            v
   [Salida en tu terminal]

Explicación de cada paso:

  1. La CLI interpreta el comando: entiende que quieres crear y arrancar un contenedor de nginx.
  2. Petición a la API: la CLI traduce esa intención en una petición a la API REST del daemon.
  3. El daemon recibe la petición y comprueba si la imagen nginx ya está disponible localmente.
  4. Descarga si es necesario: si no la tiene, el daemon la descarga (pull) desde el registro (Docker Hub por defecto).
  5. containerd prepara el contenedor: gestiona el ciclo de vida y el almacenamiento necesario.
  6. runc crea el contenedor: usando los namespaces (aislamiento) y cgroups (límites de recursos) del kernel.
  7. El contenedor arranca: el proceso de Nginx empieza a ejecutarse aislado.
  8. Respuesta a la CLI: el daemon informa del resultado y la CLI te lo muestra en la terminal.

Errores Comunes y Consejos

  • Pensar que la CLI ejecuta los contenedores: no lo hace. La CLI solo envía peticiones; el trabajo real lo hace el daemon. Si el daemon está parado, la CLI no puede hacer nada.
  • Olvidar que el daemon debe estar en marcha: el error Cannot connect to the Docker daemon casi siempre significa que el servicio no está activo o que Docker Desktop no ha terminado de arrancar.
  • Confundir los niveles: dockerd coordina, containerd gestiona el ciclo de vida y runc crea el contenedor. No son lo mismo ni hacen lo mismo.
  • Exponer la API sin protección: dar acceso al socket o a la API por red sin seguridad equivale a ceder el control total de la máquina. Trátalo con extremo cuidado.
  • Consejo: cuando algo falle, pregúntate en qué eslabón de la cadena (CLI → API → daemon → containerd → runc) podría estar el problema. Esa mentalidad te ahorrará tiempo de diagnóstico.

Ejercicios

Ejercicio 1

Describe, con tus propias palabras, los papeles de la Docker CLI y del Docker daemon, y explica por qué pueden estar en máquinas distintas.

Ejercicio 2

Ordena de mayor a menor nivel de abstracción los siguientes componentes y resume en una frase qué hace cada uno: runc, dockerd, containerd.

Ejercicio 3

Indica cuál de estos cuatro objetos de Docker está pensado para persistir datos más allá de la vida de un contenedor y por qué: imagen, contenedor, red, volumen.

Soluciones

Solución 1

La Docker CLI es la herramienta de línea de comandos que recibe tus órdenes y las traduce en peticiones a la API; actúa como un "mando a distancia". El Docker daemon (dockerd) es el proceso servidor que ejecuta el trabajo real: construir imágenes, crear y gestionar contenedores, redes y volúmenes. Pueden estar en máquinas distintas porque se comunican mediante una API REST: el cliente envía peticiones por red (o socket) y el daemon responde, así que el cliente de tu portátil puede controlar un daemon que corre en un servidor remoto.

Solución 2

De mayor a menor nivel de abstracción:

  1. dockerd (alto): recibe las peticiones de la API y coordina toda la operación.
  2. containerd (intermedio): gestiona el ciclo de vida de contenedores e imágenes y el almacenamiento.
  3. runc (bajo): crea realmente el contenedor usando namespaces y cgroups del kernel.

Solución 3

El volumen. Está diseñado precisamente para almacenar datos de forma independiente del contenedor, de modo que la información persiste aunque el contenedor se elimine y se vuelva a crear. Los contenedores son efímeros, las imágenes son plantillas de solo lectura y las redes gestionan comunicación, no datos de aplicación.

Conclusión

En esta lección hemos visto la arquitectura interna de Docker: el modelo cliente-servidor, el papel del daemon (dockerd) como motor que hace el trabajo, la CLI como mando a distancia, la API REST como idioma común, los objetos que se gestionan (imágenes, contenedores, redes y volúmenes) y las capas de bajo nivel containerd y runc. Además, hemos recorrido paso a paso lo que ocurre al ejecutar docker run. Ahora entiendes qué sucede entre bastidores cada vez que usas Docker.

En la siguiente lección, Comandos Básicos de Docker, pondremos en práctica este conocimiento aprendiendo los comandos esenciales del día a día: run, ps, images, pull, stop, rm, rmi, logs y exec, junto con la estructura general de cualquier comando de Docker.

© Copyright 2026. Todos los derechos reservados