Skip to content

9. Docker Compose

Temas del programa: 4.2

Definir una aplicación con varios servicios

Nuestra aplicación puede requerir

ReservaFIC
├── app
├── db
└── proxy

Cada servicio tiene una responsabilidad diferente

Necesitamos definir cómo se construye cómo se conecta y cómo se ejecuta cada componente

El problema de administrar cada servicio manualmente

Section titled “El problema de administrar cada servicio manualmente”
Terminal window
docker network create reservafic
docker volume create datos_pg
docker run ...
docker run ...
docker run ...

Una aplicación multicontenedor puede requerir muchas opciones de configuración

Si cada integrante del equipo ejecuta comandos diferentes el ambiente puede volverse difícil de reproducir

Docker Compose permite definir y administrar aplicaciones multicontenedor mediante un archivo de configuración

El archivo describe servicios redes volúmenes y otras opciones de ejecución

compose.yaml
│
▼
docker compose up
│
▼
Aplicación multicontenedor
services:
web:
image: nginx:alpine
ports:
- "127.0.0.1:8080:80"

Este archivo define un servicio llamado web

El servicio utiliza la imagen nginx:alpine y publica el puerto 80 del contenedor en el puerto 8080 del host

El puerto se publica solamente en la interfaz local

En el directorio que contiene compose.yaml

Terminal window
docker compose up -d

Consulta los servicios y contenedores

Terminal window
docker compose ps

Consulta los registros

Terminal window
docker compose logs

Sigue los registros

Terminal window
docker compose logs -f
Terminal window
docker compose down

Detiene y elimina los recursos de contenedores y redes del proyecto que administra Compose según su configuración

Los volúmenes no se eliminan normalmente con este comando

Terminal window
docker compose down -v

Solicita eliminar también los volúmenes asociados incluidos en el alcance del comando

Eliminar volúmenes puede provocar pérdida de datos

services:
web:
image: nginx:alpine
ports:
- "127.0.0.1:8080:80"
app:
image: php:8.3-cli
command: ["php", "-v"]

Este ejemplo demuestra la definición de dos servicios

No constituye todavía una aplicación web completa porque no conecta el servidor Nginx con una aplicación PHP funcional

Compose crea una red para el proyecto de forma predeterminada

Red del proyecto
┌──────────┐ ┌──────────┐
│ web │ │ app │
│ │ │ │
└──────────┘ └──────────┘

Los servicios conectados a esa red pueden localizarse mediante el nombre del servicio cuando la configuración y el protocolo son correctos

El nombre de servicio no reemplaza la configuración de puertos ni hace que una aplicación escuche automáticamente

services:
db:
image: postgres:16
environment:
POSTGRES_DB: reservafic
POSTGRES_USER: reservafic
POSTGRES_PASSWORD: ejemplo-no-produccion
volumes:
- datos_pg:/var/lib/postgresql/data
volumes:
datos_pg:

Este ejemplo crea un servicio de PostgreSQL y un volumen nombrado para sus datos

La contraseña es ilustrativa y no debe utilizarse en producción

services
│
└── db
│
├── image
├── environment
└── volumes
volumes
│
└── datos_pg

services define los componentes de la aplicación

environment establece variables de entorno

volumes declara almacenamiento persistente administrado por Docker

Las variables de entorno pueden servir para configurar una aplicación pero no deben considerarse un almacén de secretos de producción

Para un entorno real debemos evaluar

  • Mecanismos de gestión de secretos
  • Permisos de acceso
  • Archivos excluidos de Git
  • Rotación de credenciales
  • Separación de ambientes
  • Riesgos de exponer variables en registros o herramientas de diagnóstico

Un archivo .env tampoco debe publicarse con credenciales reales en un repositorio público

depends_on no significa que todo esté listo

Section titled “depends_on no significa que todo esté listo”

Un servicio puede haberse iniciado aunque la aplicación todavía no esté lista para recibir conexiones

Contenedor DB iniciado
│
▼
PostgreSQL inicializando
│
▼
PostgreSQL listo

El orden de inicio y la disponibilidad del servicio son conceptos distintos

Las aplicaciones deben manejar errores temporales y reintentos cuando corresponda

Un health check permite definir una comprobación de salud para un contenedor cuando la imagen o la configuración lo permiten

Servicio
│
▼
Comprobación
│
├── no saludable
│
└── saludable

Un servicio puede estar ejecutándose y aun así no responder correctamente a las solicitudes

La comprobación debe evaluar una condición significativa para el servicio

Continúa con 10. Seguridad de contenedores.