Docker 2 · Aplicaciones multi-contenedor
Al final de Docker 1 pusiste en marcha TasteMatch junto a Redis. Preparaste una imagen propia, creaste almacenamiento y una red, configuraste variables, publicaste un puerto y conectaste dos contenedores. También comprobaste el resultado, investigaste incidencias y limpiaste los recursos de la práctica.
Sabes gestionar cada pieza. Pero piensa ahora en el día siguiente: ¿podrías reproducir exactamente la misma aplicación en otro equipo sin olvidar ningún comando, nombre, montaje, puerto o variable?
Con dos contenedores ya tenemos que coordinar varias decisiones:
aplicación
├── imagen propia
├── puerto publicado
├── variables de entorno
└── red compartida
Redis
├── imagen existente
├── almacenamiento
└── red compartida
Hacerlo manualmente sigue siendo válido. El problema es mantener y compartir una secuencia cada vez más larga de comandos. Una opción olvidada puede producir una aplicación distinta; una instrucción desactualizada puede impedir que otra persona la ejecute.
De gestionar piezas a describir la aplicación
Hasta ahora el recorrido se parecía a este:
docker run ...
docker network ...
docker volume ...
-e ...
-p ...
En este curso reuniremos esas decisiones en una descripción de la aplicación:
describimos la aplicación
↓
compose.yaml
↓
docker compose
↓
servicios + redes + volúmenes + configuración
↓
aplicación multi-contenedor
El archivo compose.yaml expresará qué piezas necesita el proyecto y cómo se relacionan. Docker Compose utilizará esa descripción para gestionar el conjunto.
No necesitas memorizar todavía su sintaxis. Primero entenderemos por qué necesitamos describir la aplicación; después construiremos el archivo de forma progresiva.
Utilizaremos el comando actual docker compose y el nombre compose.yaml. En proyectos antiguos puedes encontrar docker-compose o docker-compose.yml, pero no serán la convención principal de este recorrido.
Compose organiza conceptos que ya conoces
Docker Compose no sustituye Docker ni oculta lo aprendido:
- un servicio describe cómo debe ejecutarse una parte de la aplicación, y Compose crea y gestiona los contenedores necesarios para ese servicio;
- una red sigue siendo una red Docker;
- un volumen sigue almacenando datos fuera del ciclo de vida del contenedor;
- un puerto publicado sigue conectando un puerto del host con uno del contenedor;
- una variable sigue configurando el proceso que ejecutamos;
- una imagen propia sigue necesitando un proceso de construcción.
Docker 1
conocemos y gestionamos las piezas
↓
Docker 2
describimos y gestionamos sus relaciones
Podremos seguir inspeccionando contenedores, redes y volúmenes reales. Si una ruta, un puerto o una variable están mal definidos, Compose no los arreglará por arte de magia. Comprender las piezas seguirá siendo la base para diagnosticar el conjunto.
Nuestra aplicación de referencia
TasteMatch evolucionará hacia una aplicación con varios servicios. En Docker 2 adaptaremos algunas piezas del laboratorio anterior para trabajar también con una base de datos persistente. Su arquitectura principal será sencilla para que el código no eclipse Docker:
usuario
│
▼
┌───────────────┐
│ TasteMatch │
│ web/backend │
└───────┬───────┘
│
red
│
┌───────▼───────┐
│ base de datos │
└───────┬───────┘
│
volumen
│
▼
datos
Cuando aporte valor podremos incorporar un tercer servicio, pero siempre mantendremos el foco en la aplicación completa: qué necesita, cómo se reproduce y cómo comprobamos que funciona.
Lo que aprenderás
A lo largo del curso pasarás de los comandos independientes a un flujo reproducible. Aprenderás a:
- reconocer los servicios que forman una aplicación;
- describirlos en
compose.yamlmediante imágenes propias o existentes; - construir y reconstruir los servicios que lo necesiten;
- proporcionar puertos, variables y archivos de configuración;
- comunicar servicios mediante redes y nombres;
- conservar datos con volúmenes;
- integrar una base de datos en la aplicación;
- distinguir que un contenedor haya arrancado de que su servicio esté preparado;
- expresar dependencias y comprobar disponibilidad mediante healthchecks;
- consultar estado y logs y ejecutar comandos de diagnóstico;
- mejorar imágenes para acercarlas de forma razonada a un contexto real;
- etiquetar, publicar y recuperar una imagen mediante un registry;
- integrar todo el recorrido en un proyecto final multi-contenedor.
No existe una opción que convierta por sí sola una aplicación en «lista para producción». Disponibilidad, backups, secretos, seguridad, observabilidad e infraestructura dependen del contexto y requieren decisiones adicionales. Aquí construiremos fundamentos prácticos para preparar, distribuir y diagnosticar aplicaciones con criterio.
Antes de empezar
Este curso continúa Docker 0 y Docker 1. Partimos de que ya puedes:
- trabajar con imágenes y contenedores;
- crear una imagen mediante un Dockerfile;
- utilizar puertos, redes, volúmenes y bind mounts;
- configurar contenedores con variables de entorno;
- comunicar contenedores por nombre en una red;
- consultar estado, logs e información de inspección;
- investigar un fallo cambiando una sola causa cada vez.
No volveremos a estudiar esos conceptos desde cero. Los combinaremos para responder una pregunta nueva:
¿Cómo describimos una aplicación completa para poder crearla, mantenerla y compartirla como un conjunto?
En la primera unidad retomaremos la ejecución manual que ya conoces y observaremos exactamente dónde empieza a resultar difícil de reproducir. Desde ese problema construiremos, paso a paso, el modelo de Docker Compose.