Descripción general

Docker Compose define aplicaciones multi-contenedor en un único archivo YAML. Esta chuleta cubre la estructura de compose.yaml, cada clave de servicio, opciones de entorno y configuración, redes y volúmenes, la CLI completa, archivos override y perfiles. Todos los ejemplos apuntan a Docker Compose v2 (el plugin docker compose) y la Especificación de Compose; la clave version: heredada es obsoleta e ignorada.

Estructura de compose.yaml

La estructura básica de un archivo Compose:

services:      # Define servicios contenerizados
volumes:       # Define volúmenes nombrados
networks:      # Define redes personalizadas
configs:       # Define configs (para swarm, opcional)
secrets:       # Define secretos (para swarm, opcional)

Servicios: claves básicas

Clave Propósito Ejemplo
image: <name>:<tag> Usar una imagen precompilada image: nginx:1.27
build: <path> Construir una imagen desde un Dockerfile en la ruta dada build: . o build: ./services/web
build: { context: <path>, dockerfile: <file> } Construir con contexto y ruta Dockerfile explícitos build: { context: ., dockerfile: Dockerfile.prod }
build: { context: <path>, args: { VAR: value } } Pasar argumentos de construcción build: { context: ., args: { NODE_ENV: production } }
container_name: <name> Establecer el nombre del contenedor (no recomendado para escalado) container_name: my_web_app
restart: <policy> Política de reinicio: no, always, on-failure, unless-stopped restart: unless-stopped
restart: on-failure:<max-retries> Reiniciar en fallo hasta N veces restart: on-failure:5

Redes y puertos

Clave Propósito Ejemplo
ports: [<host>:<container>] Mapear puerto del contenedor al host ports: ["8080:80"]
ports: [<host-ip>:<host>:<container>] Mapear a una IP de host específica ports: ["127.0.0.1:8080:80"]
ports: [<container>] Exponer sin mapear al host ports: ["8080"]
expose: [<port>] Exponer puerto para comunicación interna (sin mapeo al host) expose: ["8080"]
networks: [<network>] Adjuntar servicio a redes personalizadas networks: [frontend, backend]
networks: <network>: { ipv4_address: <ip> } Asignar IP estática networks: { backend: { ipv4_address: 172.20.0.2 } }
hostname: <name> Establecer nombre de host del contenedor hostname: db-server
links: [<service>] Enlazar a otro servicio (heredado, usa redes en su lugar) links: [db]
dns: [<ip>] Establecer servidores DNS dns: [8.8.8.8, 8.8.4.4]
dns_search: [<domain>] Establecer dominios de búsqueda DNS dns_search: [example.com]

Entorno y configuración

Clave Propósito Ejemplo
environment: { VAR: value } Establecer variables de entorno en línea environment: { DEBUG: "true", LOG_LEVEL: info }
environment: [VAR=value] Establecer variables de entorno como lista environment: [DEBUG=true, LOG_LEVEL=info]
env_file: <file> Cargar variables de entorno desde un archivo env_file: .env
env_file: [<file1>, <file2>] Cargar desde múltiples archivos (archivos posteriores anulan anteriores) env_file: [.env, .env.local]
working_dir: <path> Establecer directorio de trabajo dentro del contenedor working_dir: /app
command: <command> Sobrescribir CMD desde Dockerfile command: python -u app.py
command: [<cmd>, <arg1>, <arg2>] Comando como lista (forma exec, preferida) command: [python, -u, app.py]
entrypoint: <cmd> Sobrescribir ENTRYPOINT desde Dockerfile entrypoint: /bin/bash
entrypoint: [<cmd>, <arg>] ENTRYPOINT como lista (forma exec, preferida) entrypoint: [python, -u]
stdin_open: true Mantener stdin abierto incluso si no está adjunto stdin_open: true
tty: true Asignar una pseudo-terminal tty: true

Almacenamiento: volúmenes y bind mounts

Clave Propósito Ejemplo
volumes: [<host>:<container>] Bind mount un directorio del host volumes: [./data:/app/data]
volumes: [<name>:<container>] Montar un volumen nombrado volumes: [my_data:/app/data]
volumes: { <container>: {} } Volumen anónimo volumes: { /app/data: {} }
volumes: { <container>: { ro: true } } Montar solo lectura volumes: { /data: { ro: true } }
volumes: { <container>: { consistency: <mode> } } Modo de consistencia (solo macOS/Windows) volumes: { /data: { consistency: delegated } }
tmpfs: [<path>] Montar un sistema de archivos temporal tmpfs: [/tmp]

Nota: Define volúmenes nombrados en el nivel superior:

volumes:
  my_data:
    driver: local

Límites de recursos

Clave Propósito Ejemplo
cpus: <float> Limitar núcleos de CPU (p. ej., 0.5 para medio núcleo) cpus: 2
cpu_shares: <int> Peso de compartir CPU (prioridad relativa) cpu_shares: 512
mem_limit: <value> Limitar memoria (p. ej., 512m, 1g) mem_limit: 512m
memswap_limit: <value> Limitar memoria + intercambio memswap_limit: 1g
mem_reservation: <value> Límite de memoria suave (permite exceder si hay espacio) mem_reservation: 256m

Verificaciones de salud

Clave Propósito Ejemplo
healthcheck: { test: [CMD, curl, -f, 'http://localhost/health'] } Definir comando de verificación de salud (ver abajo)
healthcheck: { test: CMD curl -f http://localhost/health } Verificación de salud como cadena healthcheck: { test: CMD curl -f http://localhost/health }
healthcheck: { test: CMD-SHELL, 'pg_isready -U postgres' } Verificación de salud con shell (ver abajo)
healthcheck: { interval: 30s } Con qué frecuencia ejecutar la verificación (predeterminado: 30s) interval: 30s
healthcheck: { timeout: 5s } Tiempo de espera para la verificación (predeterminado: 30s) timeout: 5s
healthcheck: { start_period: 10s } Período de gracia antes de la primera verificación (predeterminado: 0s) start_period: 10s
healthcheck: { retries: 3 } Fallos consecutivos antes de marcar como no saludable (predeterminado: 3) retries: 3
healthcheck: disable: true Desactivar verificación de salud (si se hereda de imagen) disable: true

Ejemplo completo:

healthcheck:
  test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
  interval: 30s
  timeout: 5s
  start_period: 10s
  retries: 3

Dependencias y orden de inicio

Clave Propósito Ejemplo
depends_on: [<service>] Esperar a que se inicien los servicios (sin verificación de disponibilidad) depends_on: [db, cache]
depends_on: { <service>: { condition: service_started } } Esperar a que se inicie el servicio depends_on: { db: { condition: service_started } }
depends_on: { <service>: { condition: service_healthy } } Esperar a que el servicio sea saludable depends_on: { db: { condition: service_healthy } }
depends_on: { <service>: { condition: service_completed_successfully } } Esperar a que el servicio se complete correctamente (trabajos únicos) depends_on: { migration: { condition: service_completed_successfully } }

Precaución: condition: service_healthy requiere que el servicio tenga healthcheck. Sin él, la condición falla inmediatamente.

Ejemplo completo:

services:
  web:
    depends_on:
      db:
        condition: service_healthy
      cache:
        condition: service_started

Seguridad: secretos y configs

Clave Propósito Ejemplo
secrets: [<name>] Montar archivo secreto en /run/secrets/<name> secrets: [db_password]
configs: [<name>] Montar archivo de config en / configs: [nginx_config]

Definición en el nivel superior:

secrets:
  db_password:
    file: ./secrets/db_password.txt

configs:
  nginx_config:
    file: ./nginx.conf

Acceso en contenedor:

# En shell: cat /run/secrets/db_password

Perfiles

Los perfiles permiten incluir servicios condicionalmente.

services:
  web:
    image: nginx:latest
    # Siempre incluido

  debug:
    image: busybox:latest
    profiles: [debug]
    # Solo incluido con --profile debug

  monitoring:
    image: prom/prometheus:latest
    profiles: [monitoring, prod]
    # Incluido con --profile monitoring O --profile prod

Uso:

docker compose up                        # Incluir solo servicios sin perfiles
docker compose --profile debug up        # Incluir web + debug
docker compose --profile monitoring up   # Incluir web + monitoring
docker compose --profile debug --profile monitoring up  # Incluir los tres

Redes (nivel superior)

networks:
  frontend:
    driver: bridge
  backend:
    driver: bridge
    driver_opts:
      com.docker.network.bridge.name: br0

Uso de servicio:

services:
  web:
    networks: [frontend, backend]
  db:
    networks: [backend]

Volúmenes (nivel superior)

volumes:
  db_data:
    driver: local
  shared_cache:
    driver: local
    driver_opts:
      type: tmpfs
      device: tmpfs

Archivos override

Docker Compose carga automáticamente docker-compose.override.yaml y lo fusiona con compose.yaml.

compose.yaml (producción):

services:
  web:
    image: myapp:latest
    environment:
      LOG_LEVEL: warn

docker-compose.override.yaml (desarrollo local):

services:
  web:
    build: .
    ports:
      - "8000:8000"
    environment:
      LOG_LEVEL: debug

Resultado cuando se ejecuta docker compose up:
– Imagen se construye desde ./Dockerfile (sobrescribe image: myapp:latest)
– Puerto 8000 se expone en el host
– LOG_LEVEL se establece a debug
– Mapeo de puerto y LOG_LEVEL se fusionan

Archivo override explícito:

docker compose -f compose.yaml -f compose.prod.yaml up

Comandos CLI

Comando Propósito Ejemplo
docker compose up Crear e iniciar todos los servicios docker compose up
docker compose up -d Iniciar servicios en modo desasociado (fondo) docker compose up -d
docker compose up -d --scale web=3 Escalar un servicio a N réplicas docker compose up -d --scale web=3
docker compose down Detener y eliminar todos los servicios, redes (mantiene volúmenes) docker compose down
docker compose down -v Detener y eliminar servicios, redes, Y volúmenes docker compose down -v
docker compose down --rmi all Eliminar servicios y eliminar todas las imágenes docker compose down --rmi all
docker compose down --remove-orphans Eliminar servicios no en el archivo Compose docker compose down --remove-orphans
docker compose ps Listar servicios en ejecución docker compose ps
docker compose logs Ver logs de todos los servicios docker compose logs
docker compose logs -f Transmitir logs continuamente (seguimiento) docker compose logs -f
docker compose logs -f <service> Transmitir logs desde un servicio docker compose logs -f web
docker compose logs --tail 50 <service> Mostrar últimas 50 líneas de un servicio docker compose logs --tail 50 web
docker compose exec <service> <command> Ejecutar un comando dentro de un servicio docker compose exec web bash
docker compose exec -it <service> bash Ejecutar bash interactivamente dentro de un servicio docker compose exec -it db psql -U postgres
docker compose exec -u <user> <service> <command> Ejecutar como un usuario específico docker compose exec -u appuser web whoami
docker compose pull Extraer las últimas imágenes para todos los servicios docker compose pull
docker compose build Construir todas las imágenes (si se especifica build:) docker compose build
docker compose build --no-cache <service> Reconstruir sin caché docker compose build --no-cache web
docker compose start Iniciar servicios detenidos docker compose start
docker compose stop Detener servicios en ejecución docker compose stop
docker compose stop <service> Detener un servicio específico docker compose stop web
docker compose restart Reiniciar todos los servicios docker compose restart
docker compose restart <service> Reiniciar un servicio específico docker compose restart web
docker compose pause Pausar todos los servicios docker compose pause
docker compose unpause Reanudar servicios en pausa docker compose unpause
docker compose config Validar e imprimir la configuración final de Compose docker compose config
docker compose config --resolve-image-digests Resolver digests de imagen (útil para reproducibilidad) docker compose config --resolve-image-digests
docker compose watch Ver cambios y sincronizar/reconstruir servicios (Compose 2.22+) docker compose watch
docker compose version Mostrar versión de Docker Compose docker compose version
docker compose -f <file> <command> Especificar explícitamente un archivo Compose docker compose -f docker-compose.prod.yaml up
docker compose --project-name <name> <command> Usar un nombre de proyecto personalizado (predeterminado: nombre del directorio) docker compose --project-name myapp up

Patrones que reutilizarás

# Desarrollo con archivo override
# compose.yaml: configuración de producción
# docker-compose.override.yaml: ajustes de desarrollo local

# Base de datos con healthcheck y depends_on
services:
  db:
    image: postgres:16
    environment:
      POSTGRES_PASSWORD: secret
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
  web:
    depends_on:
      db:
        condition: service_healthy

# Aplicación de múltiples niveles
services:
  web:
    networks: [frontend, backend]
  cache:
    networks: [backend]
  db:
    networks: [backend]

# Cargar entorno desde archivo con sobrescrituras
services:
  app:
    env_file: .env
    environment:
      LOG_LEVEL: debug  # Sobrescribir desde .env

# Perfiles para servicios opcionales
  monitoring:
    profiles: [monitoring]
  debug:
    profiles: [debug]

# Usar compose watch para recarga en vivo (Compose 2.22+)
# docker compose watch
watch:
  - path: ./src
    action: sync
    target: /app/src
  - path: ./requirements.txt
    action: rebuild

Preguntas frecuentes

¿Cuál es la diferencia entre docker-compose.yml y compose.yaml?

Ambos son compatibles. Docker prefiere compose.yaml (sin guión). Ambos son equivalentes; elige una convención y adhiérete a ella. La documentación moderna usa compose.yaml.

¿Cómo establezco variables de entorno en Docker Compose?

Usa la clave environment en un servicio, o carga desde un archivo con env_file: .env. Las variables pueden estar codificadas, del shell del host (${VAR_NAME}), o desde archivos .env. Usa secretos para valores sensibles.

¿Cómo me aseguro de que un servicio se inicie antes que otro?

Usa depends_on: db: condition: service_healthy (requiere HEALTHCHECK). Solo para orden de inicio sin validación, usa el formulario corto depends_on: [db]; solo ordena el inicio y no espera a estar listo.

¿Cómo uso archivos override de Docker Compose?

Crea docker-compose.override.yaml en el mismo directorio. Compose lo carga automáticamente y lo fusiona con compose.yaml. Sobrescribe servicios específicos sin editar el archivo principal. Útil para desarrollo local vs. producción.

¿Qué son los perfiles de Docker Compose?

Los perfiles permiten incluir servicios condicionalmente. Establece profiles: [debug] en un servicio, luego usa docker compose --profile debug up para incluirlo. Útil para servicios de depuración opcionales o pilas de monitoreo.

Cómo se verificó esta guía

Escrita a mano a partir de la documentación oficial, con cada comando comprobado de nuevo y una segunda revisión antes de publicar. Última revisión: .

Fuentes oficiales consultadas para este artículo

Share.

Los comentarios están cerrados.