Manual Completo de Docker Compose

1. Introducción a Docker Compose

Docker Compose es una herramienta para definir y ejecutar aplicaciones Docker multi-contenedor. Con Compose, usas un archivo YAML para configurar los servicios de tu aplicación y luego con un solo comando, creas e inicias todos los servicios desde tu configuración.

Nota: Docker Compose es ideal para entornos de desarrollo, pruebas y despliegues en etapas, así como para flujos de trabajo CI (Integración Continua).

2. Instalación de Docker Compose

Docker Compose viene incluido con Docker Desktop para Windows y Mac. Para Linux, necesitas instalarlo por separado.

Instalación en Linux

# Descargar la versión estable actual de Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

# Aplicar permisos de ejecución al binario
sudo chmod +x /usr/local/bin/docker-compose

# Verificar la instalación
docker-compose --version

3. Conceptos Básicos

Archivo docker-compose.yml

Es el archivo de configuración principal donde defines los servicios, redes y volúmenes para tu aplicación.

Servicios (services)

Cada servicio representa un contenedor en ejecución. Puedes especificar qué imagen usar, qué puertos exponer, qué volúmenes montar, etc.

Proyectos

Docker Compose agrupa los recursos (contenedores, redes, volúmenes) bajo un nombre de proyecto. Por defecto, usa el nombre del directorio donde está el archivo docker-compose.yml.

4. Estructura del archivo docker-compose.yml

Un archivo docker-compose.yml típico tiene la siguiente estructura:

version: "3.8"  # Versión del formato del archivo

services:      # Define los servicios/contenedores
  servicio1:    # Nombre del primer servicio
    image: ...  # Configuración del servicio
    ports: ...
    volumes: ...
  
  servicio2:    # Nombre del segundo servicio
    build: ...  # Puede construir desde un Dockerfile
    environment: ...
    depends_on: ...

volumes:        # Define volúmenes persistentes
  volumen1:

networks:       # Define redes personalizadas
  red1:

5. Comandos Básicos de Docker Compose

Comando Descripción
docker-compose up Crea e inicia los contenedores
docker-compose up -d Ejecuta los contenedores en segundo plano
docker-compose down Detiene y elimina contenedores, redes, volúmenes
docker-compose ps Lista los contenedores del proyecto
docker-compose logs Muestra los logs de los contenedores
docker-compose build Reconstruye las imágenes de los servicios
docker-compose exec Ejecuta un comando en un contenedor en ejecución
docker-compose pull Descarga las imágenes de los servicios
docker-compose config Valida y muestra la configuración compilada

6. Ejemplo Básico: WordPress con MySQL

Este es un ejemplo clásico que muestra cómo levantar WordPress con una base de datos MySQL:

version: "3.8"

services:
  db:
    image: mysql:5.7
    volumes:
      - db_data:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: somewordpress
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress

  wordpress:
    depends_on:
      - db
    image: wordpress:latest
    ports:
      - "8000:80"
    restart: always
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
      WORDPRESS_DB_NAME: wordpress

volumes:
  db_data:

Para ejecutar este ejemplo:

docker-compose up -d

Luego puedes acceder a WordPress en http://localhost:8000

7. Opciones de Configuración Principales

build

Especifica la ubicación del Dockerfile para construir una imagen en lugar de usar una preexistente:

services:
  webapp:
    build:
      context: ./dir
      dockerfile: Dockerfile-alternativo
      args:
        buildno: 1

ports

Mapea puertos entre el host y el contenedor:

ports:
  - "8000:80"       # host:contenedor
  - "5000-5010:5000-5010"  # Rango de puertos
  - "6060:6060/udp" # Especificar protocolo

volumes

Monta volúmenes o directorios del host en el contenedor:

volumes:
  - /var/lib/mysql                # Volumen anónimo
  - ./datos:/var/lib/mysql        # Montaje bind (host:contenedor)
  - config:/etc/config:ro         # Volumen nombrado (solo lectura)

environment

Establece variables de entorno:

environment:
  - DEBUG=1
  - DATABASE_HOST=db

O usando un archivo .env:

env_file:
  - .env

networks

Configura redes personalizadas:

services:
  web:
    networks:
      - frontend
      - backend

networks:
  frontend:
  backend:
    driver: bridge

8. Uso de Variables de Entorno

Puedes usar variables de entorno en tu archivo docker-compose.yml:

version: "3.8"

services:
  db:
    image: "postgres:${POSTGRES_VERSION}"
    environment:
      - POSTGRES_PASSWORD=${DB_PASSWORD}

Crea un archivo .env en el mismo directorio:

POSTGRES_VERSION=13
DB_PASSWORD=misecreto

Advertencia: Nunca incluyas contraseñas o información sensible directamente en el archivo docker-compose.yml. Usa siempre variables de entorno.

9. Escalado de Servicios

Puedes escalar servicios horizontalmente con el comando scale:

docker-compose up -d --scale web=3

Esto creará 3 instancias del servicio "web". Para que funcione correctamente:

Ejemplo con Nginx como balanceador:

version: "3.8"

services:
  web:
    build: .
    # No especificamos ports aquí
    
  nginx:
    image: nginx
    ports:
      - "8080:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    depends_on:
      - web

10. Uso de Perfiles (Profiles)

Los perfiles te permiten marcar servicios para que solo se inicien en ciertos casos:

version: "3.8"

services:
  web:
    # Siempre se inicia
    
  db:
    # Siempre se inicia
    
  tests:
    profiles:
      - testing
    
  debugger:
    profiles:
      - debug

Para iniciar servicios específicos:

# Solo servicios sin perfil
docker-compose up -d

# Incluir servicios con perfil testing
docker-compose --profile testing up -d

11. Comandos Avanzados

Ejecutar comandos en un servicio

docker-compose exec db bash

Ver logs en tiempo real

docker-compose logs -f

Recrear contenedores

docker-compose up -d --force-recreate

Reconstruir e iniciar

docker-compose up -d --build

Pausar y reanudar

docker-compose pause
docker-compose unpause

12. Mejores Prácticas

Ejemplo de healthcheck

services:
  web:
    image: nginx
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost"]
      interval: 30s
      timeout: 10s
      retries: 3

13. Uso de Múltiples Archivos Compose

Puedes dividir tu configuración en varios archivos para diferentes entornos:

# Base común
docker-compose.yml

# Sobrescribe configuraciones para desarrollo
docker-compose.override.yml

# Configuraciones específicas para producción
docker-compose.prod.yml

Para usar múltiples archivos:

# Desarrollo (usa docker-compose.yml y docker-compose.override.yml por defecto)
docker-compose up -d

# Producción
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d

14. Casos de Uso Comunes

Entorno de desarrollo para una aplicación web

version: "3.8"

services:
  db:
    image: postgres:13
    volumes:
      - postgres_data:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: desarrollo
  
  redis:
    image: redis:6
  
  web:
    build: .
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    environment:
      DEBUG: "true"
    depends_on:
      - db
      - redis

volumes:
  postgres_data:

Stack completo con backend, frontend y base de datos

version: "3.8"

services:
  backend:
    build: ./backend
    ports:
      - "3000:3000"
    environment:
      DB_HOST: db
    depends_on:
      - db
  
  frontend:
    build: ./frontend
    ports:
      - "80:80"
    depends_on:
      - backend
  
  db:
    image: mongo:4.4
    volumes:
      - mongo_data:/data/db

volumes:
  mongo_data:

15. Conclusión

Docker Compose es una herramienta poderosa para gestionar aplicaciones multi-contenedor. Con un simple archivo YAML puedes definir, configurar y ejecutar todos los componentes de tu aplicación de manera consistente en diferentes entornos.

Este manual cubre los conceptos fundamentales y las características más utilizadas, pero Docker Compose tiene muchas más opciones y capacidades. Consulta la documentación oficial para explorar todas las posibilidades.