Diagrama de Contenedores C4: guía completa con ejemplos
Si solo vas a dibujar un único diagrama de arquitectura para tu sistema, que sea el diagrama de Contenedores. Es el nivel 2 del modelo C4 y, en la práctica, es el más usado de los cuatro niveles -- porque se corresponde directamente con las cosas que los equipos de ingeniería realmente construyen, despliegan y operan: aplicaciones web, APIs, bases de datos, brokers de mensajes.
Esta guía cubre todo lo que necesitas para crear un buen diagrama de Contenedores C4: qué es (y qué no es -- no, un contenedor C4 no es un contenedor Docker), qué debe contener, un ejemplo completo resuelto para un producto SaaS típico, los errores que arruinan la mayoría de los diagramas de contenedores, y cómo crear uno manualmente o generarlo a partir de tu base de código.
Si el modelo C4 es completamente nuevo para ti, empieza por nuestra guía completa del modelo C4 y luego vuelve aquí.
¿Qué es un diagrama de Contenedores C4?
El diagrama de Contenedores es el nivel 2 del modelo C4, creado por Simon Brown. Hace zoom en la única caja que representa tu sistema en el diagrama de Contexto de Sistema y revela las piezas técnicas de alto nivel que hay dentro.
En la terminología de C4, un contenedor es cualquier unidad desplegable o ejecutable de forma independiente: algo que ejecuta código o almacena datos, corre en su propio proceso (o tiene su propio ciclo de vida de almacenamiento) y, en principio, podría desplegarse de forma independiente del resto del sistema.
Esa definición abarca cosas como:
- Una aplicación de página única (React, Vue, Angular) que corre en el navegador del usuario
- Una aplicación web del lado del servidor (Next.js, Rails, Django)
- Una aplicación móvil (app de iOS, app de Android)
- Un servicio de API de backend (API en Go, servidor Node.js, servicio Spring Boot)
- Una base de datos (PostgreSQL, MongoDB, MySQL)
- Una caché (Redis, Memcached)
- Un broker de mensajes o cola (Kafka, RabbitMQ, SQS)
- Un worker en segundo plano o proceso de tareas programadas
- Un almacén de archivos o de blobs (bucket de S3, MinIO)
- Una función serverless (AWS Lambda, Cloud Functions)
La prueba de fuego es sencilla: ¿corre en su propio proceso o guarda sus propios datos? Dos paquetes de Go compilados en un mismo binario pertenecen al mismo contenedor. Dos servicios desplegados de forma independiente son dos contenedores -- aunque compartan un repositorio.
Para una definición de referencia concisa, consulta la entrada de diagrama de contenedores en nuestro glosario.
Un contenedor C4 no es un contenedor Docker
Este es el punto de confusión más común con diferencia, así que dejémoslo claro de forma explícita.
El modelo C4 es anterior a la adopción masiva de Docker, y la palabra "contenedor" en C4 significa algo más amplio: una pieza de tu sistema a nivel de ejecución. La coincidencia con Docker es casual y parcial:
- Un contenedor C4 podría correr dentro de un contenedor Docker. Tu API en Go probablemente lo hace.
- Un contenedor C4 podría correr como un proceso normal del SO, una pestaña del navegador, una app móvil o un servicio gestionado en la nube. Ninguno de esos es un contenedor Docker.
- Un único contenedor Docker podría incluso alojar varios contenedores C4 (una app más una base de datos embebida en una imagen de desarrollo), aunque eso es inusual.
Dicho de otro modo: los contenedores Docker son una tecnología de empaquetado y despliegue. Los contenedores C4 son una abstracción arquitectónica. Una SPA de React que corre en Chrome es un contenedor C4 y nunca será un contenedor Docker. Una instancia de PostgreSQL en RDS es un contenedor C4 y Docker no aparece por ninguna parte.
Cuando etiquetas una caja como "contenedor" en un diagrama C4, estás diciendo "esta es una parte ejecutable o desplegable de forma independiente de mi sistema" -- nada más.
Qué debe contener un diagrama de Contenedores
Un buen diagrama de contenedores muestra exactamente tres categorías de información:
1. Los contenedores en sí
Cada unidad desplegable o ejecutable dentro del límite de tu sistema, cada una etiquetada con su nombre, su responsabilidad y su decisión tecnológica: "Servicio de Pedidos (Go)", "Caché de Sesiones (Redis)", "App Web (SPA de React)". La etiqueta tecnológica no es decoración -- es la mitad del valor del diagrama. Es lo que permite a un nuevo ingeniero o a un equipo de plataforma razonar sobre el sistema sin abrir doce repositorios.
2. Las relaciones y los protocolos
Flechas entre contenedores, cada una etiquetada con qué fluye y cómo: "lee/escribe pedidos (SQL)", "publica eventos (AMQP)", "hace llamadas a la API (HTTPS/JSON)". Los protocolos de comunicación importan en este nivel porque condicionan las preocupaciones operativas -- políticas de red, presupuestos de latencia, semántica de reintentos, modos de fallo.
3. El contexto inmediato
Los usuarios y sistemas externos de tu diagrama de contexto, mantenidos en los bordes para que quien lee pueda ver cómo entran y salen las peticiones del sistema. No los vuelves a documentar en detalle; son anclas.
¿Para quién es este diagrama?
La audiencia del diagrama de contenedores es técnica: desarrolladores que se incorporan al equipo, arquitectos que toman decisiones estructurales e ingenieros de operaciones/plataforma que planifican despliegues, monitorización y capacidad. Es el nivel donde de verdad ocurren conversaciones como "¿deberían estos dos servicios compartir una base de datos?" o "¿qué se rompe si Redis se cae?". Las personas no técnicas deberían estar mirando el diagrama de contexto en su lugar.
Qué NO debe contener
- Módulos, clases o paquetes internos -- esos viven en el diagrama de Componentes (nivel 3)
- Detalles de infraestructura como balanceadores de carga, VPCs o nodos de Kubernetes -- esos pertenecen a un diagrama de despliegue
- Cada microinteracción -- si una relación no es arquitectónicamente significativa, déjala fuera
Ejemplo de diagrama de Contenedores: un producto web SaaS
Construyamos un ejemplo completo de diagrama de contenedores para un producto SaaS ficticio -- "InvoiceHub", una herramienta de facturación basada en web. Esta forma (SPA + API + base de datos + caché + worker + cola) describe una enorme proporción de los productos web del mundo real, así que probablemente puedas adaptarla directamente.
Los contenedores
| Contenedor | Tecnología | Responsabilidad |
|---|---|---|
| Aplicación Web | SPA de React | La interfaz que usan los clientes para crear y enviar facturas |
| Aplicación de API | Go (Fiber) | Lógica de negocio, autenticación, API REST consumida por la SPA |
| Base de Datos | PostgreSQL | Sistema de registro de cuentas, facturas y pagos |
| Caché | Redis | Almacenamiento de sesiones y caché de resúmenes de facturas en la ruta caliente |
| Cola de Mensajes | RabbitMQ | Desacopla el trabajo lento (renderizado de PDF, correos) de las peticiones de la API |
| Worker en Segundo Plano | Go | Consume mensajes de la cola: renderiza PDFs, envía correos, sincroniza estados de pago |
Las relaciones
[Customer] --> [Web Application (React SPA)] : Uses (HTTPS)
[Web Application] --> [API Application (Go)] : Makes API calls (HTTPS/JSON)
[API Application] --> [Database (PostgreSQL)] : Reads/writes invoices and accounts (SQL/TCP)
[API Application] --> [Cache (Redis)] : Reads/writes sessions and cached summaries (RESP)
[API Application] --> [Message Queue (RabbitMQ)] : Publishes invoice.created, email.requested (AMQP)
[Background Worker (Go)] --> [Message Queue] : Consumes jobs (AMQP)
[Background Worker] --> [Database (PostgreSQL)] : Updates job and payment status (SQL/TCP)
[Background Worker] --> [Email Service (SendGrid)] : Sends invoice emails (HTTPS/REST)
[API Application] --> [Payment Gateway (Stripe)] : Creates payment links, receives webhooks (HTTPS/REST)
Qué te dice este diagrama
Vuelve a leer esa lista y fíjate en cuántas preguntas concretas de ingeniería responde:
- ¿Dónde vive el estado? En dos lugares: PostgreSQL (duradero) y Redis (efímero). Si alguna vez has debatido si las sesiones sobreviven a un reinicio de Redis, el diagrama hace visible la pregunta.
- ¿Cuál es el radio de impacto de un fallo? El worker y la API comparten la base de datos. Que RabbitMQ se caiga significa que las facturas siguen creándose pero los correos se acumulan en cola -- por diseño.
- ¿Cuáles son los límites de confianza? La SPA corre en dispositivos cliente no confiables; todo lo que puede hacer pasa por la autenticación de la API.
- ¿Qué necesita operaciones para arrancar? Seis cosas, con sus protocolos. Esa es tu checklist de monitorización y, más o menos, tu archivo docker-compose.
Un nuevo desarrollador puede asimilar esto en dos minutos. Ese es todo el propósito del nivel 2 del modelo C4.
Errores comunes en los diagramas de Contenedores
La mayoría de los diagramas de contenedores fallan de una de unas pocas formas predecibles.
Confundir contenedores con componentes
Si tu diagrama de contenedores muestra "OrderController", "InvoiceRepository" o "AuthMiddleware", has hecho zoom un nivel de más. Esos son componentes -- piezas internas dentro de un contenedor -- y pertenecen a un diagrama de Componentes de nivel 3. La prueba: ¿se puede desplegar o ejecutar por sí solo? Una clase de tipo repositorio no puede. Mantén cada diagrama en un único nivel de zoom; mezclar niveles es la forma más rápida de producir un diagrama ilegible.
Omitir los almacenes de datos
Los equipos a menudo dibujan solo las cosas para las que escribieron código y olvidan que las bases de datos, las cachés y las colas también son contenedores. Un diagrama de contenedores sin sus almacenes de datos oculta exactamente la información que más necesitan los arquitectos y los ingenieros de operaciones: dónde vive el estado, qué se comparte, qué es un único punto de fallo. Si tu sistema usa PostgreSQL, Redis y S3, los tres van en el diagrama.
Dibujar el despliegue en lugar de la estructura de ejecución
Un diagrama de contenedores no es un diagrama de infraestructura. Los balanceadores de carga, los pods de Kubernetes, los grupos de autoescalado, las zonas de disponibilidad y el número de réplicas son preocupaciones de despliegue -- C4 tiene un diagrama de despliegue complementario aparte para eso. El diagrama de contenedores responde a "¿cuáles son las piezas lógicas de ejecución y cómo se comunican?", no a "¿cuántas instancias corren dónde?". Dibujar tres cajas idénticas de "API" porque corres tres réplicas añade ruido, no información.
Relaciones sin etiquetar o vagas
Una flecha que solo dice "usa" desperdicia el potencial del diagrama. "Hace llamadas a la API (HTTPS/JSON)", "publica eventos de pedido (AMQP)", "lee/escribe sesiones (RESP)" -- el verbo y el protocolo convierten una imagen en documentación.
Dejar que se pudra
El error más dañino ni siquiera está en el diagrama. Un diagrama de contenedores dibujado hace dieciocho meses que todavía muestra el monolito que desde entonces has dividido en cuatro servicios induce a error de forma activa a cada nuevo lector. La documentación de arquitectura obsoleta es peor que ninguna -- por eso mantener el diagrama sincronizado con el código importa más que lo bonito que sea.
Cómo crear un diagrama de Contenedores
Manualmente
Puedes construir un diagrama de contenedores sólido en menos de una hora:
- Parte de tu diagrama de contexto. Mantén a los usuarios y sistemas externos en los bordes.
- Lista tus unidades desplegables. Recorre tus repositorios, tu archivo docker-compose, tu consola en la nube. Todo lo que corre como su propio proceso o almacena datos es un candidato.
- Añade los almacenes de datos explícitamente. Bases de datos, cachés, colas, almacenamiento de blobs.
- Dibuja las relaciones. Por cada par de contenedores que se comunican, añade una flecha con una frase verbal y un protocolo.
- Etiqueta las tecnologías. Nombre y tecnología en cada caja.
- Revísalo con el equipo. La discusión que esto provoca ("espera, ¿el worker habla con Stripe directamente?") suele valer más que el diagrama en sí.
Cualquier herramienta sirve -- Structurizr, PlantUML con la extensión C4, draw.io, incluso una pizarra. La notación importa mucho menos que el contenido y la disciplina de mantenerlo actualizado.
Con Archyl
El enfoque manual tiene una debilidad estructural: captura una instantánea, y el software no se queda quieto. Archyl aborda el diagrama de contenedores desde la dirección opuesta -- deriva el modelo a partir del código:
- Descubrimiento por IA a partir de tu base de código. Conecta un repositorio y el descubrimiento por IA de Archyl analiza la estructura de tu código, la configuración y los manifiestos de dependencias para proponer un borrador de modelo C4 -- sistemas, contenedores, componentes y las relaciones entre ellos. Revisas y apruebas las sugerencias en lugar de dibujar cajas de memoria.
- La detección de drift lo mantiene honesto. Una vez que el modelo existe, Archyl compara de forma continua los contenedores documentados con lo que la base de código muestra de verdad y expone una puntuación de drift. Cuando alguien divide un servicio o cambia RabbitMQ por Kafka, te enteras por el panel, no por una sesión de onboarding confusa seis meses después.
- Arquitectura como Código. ¿Prefieres texto? Puedes definir tu modelo C4 completo -- contenedores, tecnologías, relaciones -- en YAML, versionarlo junto a tu código y dejar que Archyl renderice los diagramas interactivos. Los cambios en el diagrama pasan por pull requests como todo lo demás.
En cualquier caso, el objetivo es el mismo: un diagrama de contenedores que sea preciso hoy y siga siéndolo el próximo trimestre.
Preguntas frecuentes
¿Es un contenedor C4 lo mismo que un contenedor Docker?
No. Un contenedor C4 es una abstracción arquitectónica: cualquier unidad desplegable o ejecutable de forma independiente de un sistema, como una app web, una API, una base de datos o un broker de mensajes. Un contenedor Docker es una tecnología de empaquetado. Muchos contenedores C4 resultan desplegarse como contenedores Docker, pero muchos no -- una SPA de React corre en un navegador, una app móvil corre en un teléfono y una base de datos gestionada corre como un servicio en la nube. El nombre compartido es un desafortunado accidente de la historia.
¿Qué es el nivel 2 del modelo C4?
El nivel 2 del modelo C4 es el diagrama de contenedores. Hace zoom en un sistema de software (la única caja del diagrama de contexto de nivel 1) y muestra las unidades desplegables/ejecutables que hay dentro, sus decisiones tecnológicas y los protocolos que usan para comunicarse. Se sitúa entre el diagrama de contexto (nivel 1) y el diagrama de componentes (nivel 3).
¿Cuántos contenedores debe mostrar un diagrama de contenedores?
No hay una regla estricta, pero la legibilidad se degrada rápido más allá de 15-20 contenedores. Si tu sistema tiene de verdad más, divide la vista: un diagrama de contenedores por subsistema, o agrupa visualmente los contenedores relacionados. Si tienes cientos, probablemente estés documentando varios sistemas y necesites modelos C4 separados enlazados a nivel de contexto.
¿Debe cada microservicio ser un contenedor separado?
Sí -- por definición. Cada servicio desplegable de forma independiente es su propio contenedor, junto con la base de datos de cada servicio si sigues el patrón de base-de-datos-por-servicio. Esa es también una prueba útil de olor a código: si tus "microservicios" no se pueden dibujar como contenedores separados porque comparten un proceso o no pueden desplegarse de forma independiente, puede que sean un monolito distribuido.
¿Listo para generar tu diagrama de contenedores en lugar de dibujarlo? Prueba Archyl gratis y obtén un modelo C4 a partir de tu base de código en minutos. Sigue explorando la serie C4: ¿Qué es el modelo C4? Guía completa | Guía del diagrama de Contexto de Sistema C4 | Guía del diagrama de Componentes C4.