Día 13 - Docker Compose
🧩 El futuro de las multiaplicaciones
Hoy vamos a dominar Docker Compose, que viene integrado con Docker Desktop y representa el estándar actual para gestionar aplicaciones multicontenedor. ¡Olvídate de los comandos complejos y las configuraciones tediosas!
🆕 ¿Qué hay de nuevo en Docker Compose?
Docker Compose V2 está escrito en Go (vs Python en v1) y trae:
- ⚡ Performance mejorada - Hasta 3x más rápido
- 🔧 Integración nativa con Docker Desktop
- 🎯 Nuevo comando:
docker compose
(sin guión) - 📦 Sin instalación separada - Ya viene con Docker Desktop
- 🚀 Mejor manejo de dependencias y redes
💡 Nota importante: El comando cambió de
docker-compose
adocker compose
(sin guión)
📋 Verificando tu instalación
# Verificar Docker Desktop y Compose V2
docker --version
docker compose version
# Deberías ver algo como:
# Docker Compose version v2.24.x
🏗️ Anatomía moderna del docker-compose.yml
# ✅ SIN version: - Docker Compose V2 detecta automáticamente la mejor versión
services:
frontend:
build:
context: ./frontend
dockerfile: Dockerfile
ports:
- "3000:3000"
environment:
- REACT_APP_API_URL=http://localhost:8000
depends_on:
- backend
networks:
- app-network
restart: unless-stopped
db:
image: mongo:7-jammy
ports:
- "27017:27017"
environment:
- MONGO_INITDB_ROOT_USERNAME=admin
- MONGO_INITDB_ROOT_PASSWORD=password123
volumes:
- mongo_data:/data/db
networks:
- app-network
healthcheck:
test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
restart: unless-stopped
networks:
app-network:
driver: bridge
name: mi-app-network
volumes:
mongo_data:
driver: local
name: mi-app-mongo-data
Este archivo docker-compose.yml
define y configura servicios de contenedores Docker para facilitar el despliegue y la orquestación de aplicaciones. Permite levantar múltiples servicios, especificar redes, volúmenes y variables de entorno, simplificando el desarrollo y la administración de entornos multi-contenedor.
Propiedades principales del docker-compose.yml
-
services:
Define los servicios (contenedores) que forman tu aplicación. Cada clave bajoservices
es un servicio independiente.-
frontend:
Servicio para la aplicación frontend (por ejemplo, React).build
:context
: Carpeta donde está el código fuente a construir.dockerfile
: Archivo Dockerfile a usar para construir la imagen.
ports
:"3000:3000"
: Expone el puerto 3000 del contenedor al 3000 de tu máquina.
environment
:- Variables de entorno para el contenedor (ejemplo: URL de la API).
depends_on
:- Indica que este servicio depende de que otro (ej: backend) esté listo antes de iniciar.
networks
:- Redes a las que se conecta el servicio.
restart
:- Política de reinicio automático si el contenedor se detiene.
-
db:
Servicio para la base de datos MongoDB.image
:- Imagen de Docker a usar (ej: mongo:7-jammy).
ports
:"27017:27017"
: Expone el puerto estándar de MongoDB.
environment
:- Variables de entorno para inicializar MongoDB (usuario y contraseña).
volumes
:- Monta un volumen persistente para los datos de la base.
networks
:- Redes a las que se conecta el servicio.
healthcheck
:- Prueba periódica para verificar que MongoDB está listo y responde.
restart
:- Política de reinicio automático.
-
-
networks:
Define redes personalizadas para aislar y conectar servicios entre sí. -
volumes:
Define volúmenes persistentes para que los datos no se pierdan si el contenedor se elimina.
💡 Tip:
Estas propiedades permiten definir, conectar y administrar fácilmente múltiples servicios y recursos en un solo archivo, facilitando el despliegue y la gestión de aplicaciones complejas.
Para profundizar más y consultar todas las opciones disponibles, revisa la documentación oficial:
🚀 Comandos esenciales de Docker Compose V2
Comandos básicos
# Levantar todos los servicios
docker compose up
# Modo detached (en segundo plano)
docker compose up -d
# Reconstruir imágenes antes de levantar
docker compose up --build
# Levantar servicios específicos
docker compose up frontend backend
# Ver estado de servicios
docker compose ps
# Ver logs en tiempo real
docker compose logs -f
# Ver logs de un servicio específico
docker compose logs -f backend
# Parar servicios sin eliminar contenedores
docker compose stop
# Parar y eliminar contenedores, redes y volúmenes anónimos
docker compose down
# Eliminar también volúmenes nombrados
docker compose down --volumes
# Eliminar todo incluyendo imágenes
docker compose down --rmi all --volumes
Comandos avanzados
# Ejecutar comandos en servicios corriendo
docker compose exec backend npm run test
docker compose exec db mongosh
# Ejecutar comandos sin servicio corriendo
docker compose run --rm backend npm install
# Escalar servicios (crear múltiples instancias)
docker compose up --scale backend=3
# Ver configuración parseada
docker compose config
# Validar archivo compose
docker compose config --quiet
# Reiniciar servicios específicos
docker compose restart nginx
# Ver uso de recursos
docker compose top
Probemos un WordPress con Docker Compose
# docker-compose.yml - WordPress Moderno con Docker Compose V2+
services:
wordpress:
image: wordpress:php8.2-apache
container_name: wp-web
restart: unless-stopped
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: wpuser
WORDPRESS_DB_PASSWORD: wppass123
WORDPRESS_DB_NAME: wpdb
volumes:
- wp_data:/var/www/html
- ./wp-content:/var/www/html/wp-content # Para desarrollo personalizado
depends_on:
db:
condition: service_healthy
networks:
- wp_network
db:
image: mariadb:11.3
container_name: wp-db
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: rootpass123
MYSQL_DATABASE: wpdb
MYSQL_USER: wpuser
MYSQL_PASSWORD: wppass123
volumes:
- db_data:/var/lib/mysql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 5s
timeout: 5s
retries: 5
networks:
- wp_network
phpmyadmin:
image: phpmyadmin:latest
container_name: wp-admin
restart: unless-stopped
ports:
- "8081:80"
environment:
PMA_HOST: db
PMA_USER: wpuser
PMA_PASSWORD: wppass123
depends_on:
- db
networks:
- wp_network
volumes:
wp_data:
db_data:
networks:
wp_network:
driver: bridge
🔥 Características clave:
-
Stack Completo:
- WordPress (última versión PHP 8.2)
- MariaDB 11.3 (alternativa óptima a MySQL)
- phpMyAdmin para gestión de bases de datos
-
Buenas Prácticas:
- ✅ Volúmenes persistentes para datos y DB
- ✅ Healthcheck en MariaDB
- ✅ Variables de entorno separadas
- ✅ Red aislada para seguridad
-
Configuración para Desarrollo:
- Mapeo directo de
wp-content
para temas/plugins - Puertos accesibles:
- WordPress:
http://localhost:8080
- phpMyAdmin:
http://localhost:8081
- WordPress:
- Mapeo directo de
🚀 Cómo usarlo:
- Crea un directorio y guarda el archivo como
docker-compose.yml
- Ejecuta:
docker compose up -d
- Accede a WordPress en tu navegador y completa la instalación.
📌 Notas importantes:
- Seguridad en Producción:
- Cambia todas las contraseñas
- Usa secrets para las credenciales:
secrets:
db_password:
file: ./secrets/db_password.txt
- Performance:
- Para alta demanda, añade:
wordpress:
deploy:
resources:
limits:
cpus: '1'
memory: 512M
- Para alta demanda, añade:
🛠️ Comandos útiles:
Comando | Descripción |
---|---|
docker compose logs -f wordpress | Ver logs en tiempo real |
docker compose exec db mysql -u wpuser -p | Acceder a MySQL CLI |
docker compose down --volumes | Borrar TODO (incluyendo datos) |
🔧 Trucos y mejores prácticas
1. Healthchecks inteligentes
services:
api:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
2. Depends_on con condiciones
services:
app:
depends_on:
db:
condition: service_healthy
redis:
condition: service_started
3. Variables de entorno avanzadas
services:
app:
environment:
- NODE_ENV=${NODE_ENV:-development}
- PORT=${APP_PORT:-3000}
- DATABASE_URL=${DATABASE_URL:?error} # Obligatoria
4. Extensión de configuraciones
# docker-compose.yml
services:
app: &app
build: .
environment:
- NODE_ENV=production
# docker-compose.override.yml (para desarrollo)
services:
app:
<<: *app
environment:
- NODE_ENV=development
volumes:
- .:/app
🚨 Debugging y troubleshooting
Comandos útiles para debugging
# Ver configuración final parseada
docker compose config
# Inspeccionar redes
docker network ls
docker network inspect mern-app-network
# Ver volúmenes
docker volume ls
docker volume inspect mern-mongo-data
# Logs detallados con timestamps
docker compose logs -f --timestamps
# Ver procesos dentro de contenedores
docker compose top
# Estadísticas de uso
docker stats $(docker compose ps -q)
# Acceder a shell de contenedor
docker compose exec backend bash
docker compose exec db mongosh
Problemas comunes y soluciones
1. Puerto ya en uso:
# Ver qué proceso usa el puerto
lsof -i :3000
# Cambiar puerto en .env o docker-compose.yml
2. Problemas de red:
# Recrear redes
docker compose down
docker network prune
docker compose up
3. Volúmenes corruptos:
# Limpiar volúmenes
docker compose down --volumes
docker volume prune
✅ Tarea Práctica: Aplicación Node.js + MongoDB con Docker Compose**
Implementar una aplicación Node.js con MongoDB usando Docker Compose, asegurando persistencia de datos y conexión entre servicios.
📌 Parte 1: Configuración Básica
-
Estructura del proyecto:
mkdir node-mongo-app && cd node-mongo-app
mkdir backend
touch backend/{server.js,package.json,Dockerfile} docker-compose.yml -
Archivos base:
backend/server.js
(API simple):const express = require('express');
const mongoose = require('mongoose');
const app = express();
mongoose.connect('mongodb://db:27017/mydb');
app.get('/', (req, res) => {
res.send('¡API conectada a MongoDB con Docker!');
});
app.listen(3000, () => console.log('Server running on port 3000'));backend/Dockerfile
:FROM node:18-alpine
WORKDIR /app
COPY package.json .
RUN npm install
COPY . .
CMD ["node", "server.js"]
-
docker-compose.yml:
services:
backend:
build: ./backend
ports:
- "3000:3000"
depends_on:
db:
condition: service_healthy
db:
image: mongo:6
volumes:
- db_data:/data/db
healthcheck:
test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"]
interval: 5s
timeout: 3s
retries: 5
volumes:
db_data:
🛠️ Parte 2: Ejecución y Verificación
- Inicia los servicios:
docker compose up -d
- Prueba la API:
curl http://localhost:3000
# Deberías ver: "¡API conectada a MongoDB con Docker!" - Verifica la base de datos:
docker compose exec db mongosh --eval "show dbs"
🔐 Parte 3: Persistencia y Debugging
- Detén y reinicia los contenedores:
docker compose down && docker compose up -d
- Verifica que los datos de MongoDB persistan:
- Crea una colección:
docker compose exec db mongosh --eval "db.test.insertOne({name: 'Ejemplo'})"
- Reinicia y comprueba que sigue existiendo.
- Crea una colección:
💡 Bonus (Avanzado)
Añade un frontend con React:
- Agrega este servicio al
docker-compose.yml
:frontend:
image: node:18-alpine
working_dir: /app
volumes:
- ./frontend:/app
ports:
- "5173:5173"
command: ["npm", "run", "dev"]
depends_on:
- backend
💡 Tips de Roxs
"Docker Compose es como tener un director de orquesta para tus contenedores. Un solo comando y toda tu aplicación cobra vida."
Pro Tips:
- Usa
.env
para todo lo configurable - Healthchecks en servicios críticos
- Perfiles para separar entornos
- Nombres explícitos para redes y volúmenes
- El nuevo comando
docker compose
(sin guión)
Usá el hashtag #DevOpsConRoxs o compartilo en el canal de la comunidad. 🎯