Tutoriales 10 min de lectura

Docker Compose para principiantes — guía completa con ejemplos

Aprende a usar Docker Compose desde cero para levantar aplicaciones multi-contenedor con un solo comando. Incluye ejemplos prácticos con WordPress, PostgreSQL y más.

Terminal mostrando un archivo docker-compose.yml con múltiples servicios levantándose en paralelo
Terminal mostrando un archivo docker-compose.yml con múltiples servicios levantándose en paralelo

Si ya sabes usar Docker para correr un contenedor individual, el siguiente paso natural es Docker Compose. En lugar de levantar cada contenedor por separado con comandos largos de docker run, defines todo en un archivo YAML y lo arrancas con un solo comando: docker compose up.

En esta guía vas a aprender Docker Compose desde cero — desde la instalación hasta desplegar una aplicación completa con base de datos, caché y volúmenes persistentes.

Requisitos previos

Necesitas tener Docker instalado en tu máquina. Docker Compose viene incluido en Docker Desktop (Mac y Windows) y en las versiones recientes del paquete docker-ce en Linux.

Verifica que lo tienes instalado:

docker compose version

Si ves algo como Docker Compose version v2.x.x, estás listo.

Docker Compose V2

Esta guía usa la sintaxis moderna docker compose (con espacio). La versión antigua docker-compose (con guión) está deprecada desde 2023. Si aún usas la versión con guión, actualiza tu instalación de Docker.

¿Qué es Docker Compose?

Docker Compose es una herramienta que permite definir y ejecutar aplicaciones multi-contenedor. En lugar de ejecutar cada contenedor manualmente, defines todos los servicios, redes y volúmenes en un archivo docker-compose.yml y los gestionas como una unidad.

Sin Docker ComposeCon Docker Compose
Un comando docker run por cada servicioUn solo docker compose up
Redes creadas manualmenteRed creada automáticamente entre servicios
Variables de entorno pasadas en la línea de comandosVariables definidas en archivo .env
Volúmenes gestionados individualmenteVolúmenes declarados y gestionados juntos
Reinicio manual si algo fallarestart: unless-stopped integrado

Tu primer docker-compose.yml

Empecemos con un ejemplo mínimo: un servidor Nginx sirviendo una página estática.

# docker-compose.yml
services:
  web:
    image: nginx:alpine
    ports:
      - "8080:80"
    volumes:
      - ./html:/usr/share/nginx/html:ro

Crea un directorio html con un archivo index.html:

mkdir html
echo "<h1>Hola desde Docker Compose</h1>" > html/index.html

Levanta el servicio:

docker compose up -d

Abre http://localhost:8080 y verás tu página. Para detener todo:

docker compose down

Eso es Docker Compose en su forma más simple. Ahora vamos con ejemplos reales.

Ejemplo 1: WordPress con MySQL

Este es uno de los usos más comunes. Un WordPress completo con su base de datos, todo definido en un archivo:

# docker-compose.yml
services:
  wordpress:
    image: wordpress:6
    restart: unless-stopped
    ports:
      - "8080:80"
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_NAME: wordpress
      WORDPRESS_DB_USER: wp_user
      WORDPRESS_DB_PASSWORD: ${DB_PASSWORD}
    volumes:
      - wp_data:/var/www/html
    depends_on:
      db:
        condition: service_healthy

  db:
    image: mysql:8
    restart: unless-stopped
    environment:
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wp_user
      MYSQL_PASSWORD: ${DB_PASSWORD}
      MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
    volumes:
      - db_data:/var/lib/mysql
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  wp_data:
  db_data:

Crea un archivo .env con las contraseñas:

# .env
DB_PASSWORD=contraseña_segura_123
DB_ROOT_PASSWORD=root_seguro_456
docker compose up -d

Seguridad

Nunca pongas contraseñas directamente en el docker-compose.yml. Usa un archivo .env y agrégalo a tu .gitignore para que no se suba al repositorio.

Conceptos clave de este ejemplo

depends_on con healthcheck — WordPress no arranca hasta que MySQL esté saludable. Sin esto, WordPress podría intentar conectarse antes de que la base de datos esté lista y fallar.

volumes nombradoswp_data y db_data son volúmenes persistentes. Si haces docker compose down, los datos se conservan. Si haces docker compose down -v, se eliminan los volúmenes y los datos.

restart: unless-stopped — Si el contenedor se cae o el servidor se reinicia, Docker lo levanta automáticamente. Solo se detiene si tú lo detienes manualmente.

Ejemplo 2: Aplicación con PostgreSQL y Redis

Un stack más realista para una aplicación empresarial — una API con PostgreSQL como base de datos y Redis como caché:

# docker-compose.yml
services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    restart: unless-stopped
    ports:
      - "3000:3000"
    environment:
      DATABASE_URL: postgresql://app:${DB_PASSWORD}@db:5432/miapp
      REDIS_URL: redis://cache:6379
      NODE_ENV: production
    depends_on:
      db:
        condition: service_healthy
      cache:
        condition: service_started

  db:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
      POSTGRES_DB: miapp
      POSTGRES_USER: app
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes:
      - pg_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U app -d miapp"]
      interval: 10s
      timeout: 5s
      retries: 5

  cache:
    image: redis:7-alpine
    restart: unless-stopped
    command: redis-server --maxmemory 256mb --maxmemory-policy allkeys-lru
    volumes:
      - redis_data:/data

volumes:
  pg_data:
  redis_data:

Conceptos nuevos

build — En lugar de usar una imagen pre-construida, Docker Compose construye la imagen desde tu Dockerfile. Cada vez que hagas docker compose build, se reconstruye con tus cambios.

command — Sobreescribe el comando por defecto del contenedor. Aquí configuramos Redis con un límite de memoria de 256 MB y política de evicción LRU (elimina las claves menos usadas cuando se llena).

Comandos esenciales

Estos son los comandos que vas a usar todos los días:

# Levantar todos los servicios en background
docker compose up -d

# Ver logs de todos los servicios
docker compose logs -f

# Ver logs de un servicio específico
docker compose logs -f db

# Detener todos los servicios (conserva datos)
docker compose down

# Detener y eliminar volúmenes (¡borra datos!)
docker compose down -v

# Reconstruir imágenes y levantar
docker compose up -d --build

# Ver estatus de los servicios
docker compose ps

# Ejecutar un comando dentro de un contenedor
docker compose exec db psql -U app -d miapp

# Escalar un servicio (levantar múltiples réplicas)
docker compose up -d --scale app=3

Redes en Docker Compose

Docker Compose crea automáticamente una red para tu stack. Todos los servicios definidos en el mismo docker-compose.yml pueden comunicarse entre sí usando el nombre del servicio como hostname.

En el ejemplo anterior, la aplicación se conecta a PostgreSQL usando db como hostname y a Redis usando cache. No necesitas IPs, no necesitas configurar nada — Docker Compose lo resuelve automáticamente.

┌─────────────────────────────────────────┐
│        Red: miapp_default               │
│                                         │
│  ┌─────┐    ┌──────┐    ┌───────┐      │
│  │ app │───▶│  db  │    │ cache │      │
│  │:3000│    │:5432 │    │:6379  │      │
│  └─────┘    └──────┘    └───────┘      │
│      │                                   │
│      ▼                                   │
│  Puerto 3000 expuesto al host           │
└─────────────────────────────────────────┘

Si necesitas que dos stacks diferentes se comuniquen, puedes crear redes externas:

networks:
  shared:
    external: true

Variables de entorno y archivos .env

Docker Compose lee automáticamente el archivo .env en el mismo directorio que tu docker-compose.yml. Las variables se sustituyen con la sintaxis ${VARIABLE}:

# .env
DB_PASSWORD=mi_contraseña_segura
POSTGRES_VERSION=16
APP_PORT=3000
# docker-compose.yml
services:
  db:
    image: postgres:${POSTGRES_VERSION}-alpine
    environment:
      POSTGRES_PASSWORD: ${DB_PASSWORD}
  app:
    ports:
      - "${APP_PORT}:3000"

Para diferentes entornos (desarrollo, staging, producción), puedes tener archivos separados:

# Desarrollo (usa .env por defecto)
docker compose up -d

# Producción (usa .env.production)
docker compose --env-file .env.production up -d

Buenas prácticas

Después de usar Docker Compose en decenas de proyectos empresariales, estas son las prácticas que recomendamos:

Siempre usa volúmenes nombrados para datos persistentes — Los volúmenes anónimos son difíciles de rastrear y respaldar. Los nombrados son explícitos y aparecen en docker volume ls.

Siempre define healthchecks en bases de datos — Un depends_on sin healthcheck solo espera a que el contenedor arranque, no a que el servicio esté listo. La base de datos puede tardar varios segundos en aceptar conexiones después de arrancar.

Nunca pongas secretos en el docker-compose.yml — Usa .env para desarrollo y Docker Secrets o variables de entorno del sistema para producción.

Fija versiones de imagen — Usa postgres:16-alpine, no postgres:latest. Latest puede cambiar en cualquier momento y romper tu aplicación sin aviso.

Usa restart: unless-stopped — Tus contenedores se recuperan automáticamente de fallos y reinicios del servidor, pero puedes detenerlos manualmente cuando necesites.

Usa docker compose logs -f para debugging — Es tu primera herramienta de diagnóstico. Si algo no funciona, los logs te dirán qué pasó.

Siguientes pasos

Con Docker Compose dominado, el siguiente nivel es:

  • Docker en producción — configurar TLS, backups automatizados de volúmenes y monitoreo con Prometheus y Grafana
  • CI/CD — integrar docker compose build y docker compose push en tu pipeline de GitHub Actions o GitLab CI
  • Kubernetes — cuando necesitas múltiples servidores, auto-scaling y alta disponibilidad real
  • Proxmox — virtualización para aislar tus hosts de Docker en ambientes empresariales

Contenedores empresariales

¿Necesitas ayuda para containerizar tu aplicación?

Te ayudamos a diseñar la arquitectura de contenedores y Docker Compose para tu ERP, CRM o aplicación a medida.

Agendar consultoría

Preguntas frecuentes

Temas relacionados

#docker#docker-compose#contenedores#devops#tutorial

¿Te fue útil? Compártelo

Artículos relacionados

Ver todos

Consultoría gratuita

¿Necesitas ayuda para containerizar tu aplicación empresarial?

Te ayudamos a diseñar la arquitectura de contenedores, Docker Compose y despliegue para tu ERP, CRM o aplicación a medida.

Agendar consultoría