Guía rápida de Docker Compose: los comandos más útiles con ejemplos

Por cierto, docker-compose es diferente de docker compose...

Índice

Aquí tienes una hoja de referencia rápida de Docker Compose con ejemplos anotados para que domines los archivos y comandos de Compose rápidamente.

Esta guía forma parte de Herramientas para desarrolladores: La guía completa para flujos de trabajo de desarrollo modernos.

Prerequisitos

Docker Engine debe estar instalado antes de usar Compose. En Ubuntu, sigue Instalar Docker en Ubuntu para elegir el método de instalación adecuado y configurar el plugin docker compose.

docker-compose schema

Referencia del archivo Compose: docker-compose.yml

Estructura central:

version: '3'       # Versión del formato del archivo Compose

services:
  web:
    image: nginx:latest
    ports:
      - "8080:80"   # Puerto 8080 del host:Puerto 80 del contenedor
  db:
    image: postgres
    environment:            # Variables de entorno
      POSTGRES_PASSWORD: example
    volumes:
      - db_data:/var/lib/postgresql/data

networks:          # Red personalizada
  appnet:
    driver: bridge

volumes:           # Volumen con nombre
  db_data:
  • services: Cada contenedor de tu aplicación multi-contenedor. En el ejemplo anterior tenemos dos servicios: web y db. Para operaciones individuales de contenedores, consulta la Hoja de referencia de Docker.
  • networks & volumes: Definen redes aisladas y almacenamiento persistente; aquí tenemos la red appnet y el volumen db_data.

Ejemplos

Servicio único con mapeo de puertos

services:
  app:
    build: .
    ports:
      - "8000:80"   # Puerto 8000 del host:Puerto 80 del contenedor

Expone la aplicación en el puerto 8000 del host y compila desde el Dockerfile en el directorio actual.

Multi-servicio con volumen compartido y red personalizada

version: '3'
services:
  web:
    build: .
    ports:
      - "5000:5000"
    volumes:
      - type: bind
        source: ./app
        target: /app
    networks:
      - mynet
  db:
    image: postgres
    volumes:
      - db_data:/var/lib/postgresql/data
    networks:
      - mynet

networks:
  mynet:

volumes:
  db_data:

Web y DB en la misma red; DB usa un volumen con nombre persistente: db_data.

Uso de contexto de compilación y ruta del Dockerfile

Puedes compilar imágenes docker bajo demanda desde el Dockerfile especificado en docker-compose.yml.

services:
  app:
    build:
      context: .
      dockerfile: docker/MyDockerfile

Compartición de datos entre servicios

services:
  web:
    image: nginx
    volumes:
      - shared_data:/usr/share/nginx/html
  worker:
    image: myworker
    volumes:
      - shared_data:/usr/src/app/data

volumes:
  shared_data:

Ambos servicios acceden al mismo volumen (para archivos estáticos o intercambios de datos) - shared_data.

Opciones avanzadas del archivo Compose

  • environment: Establece variables ENV para los contenedores.
  • depends_on: Controla el orden de inicio de los servicios.
  • deploy.replicas: Escala el servicio en modo Swarm.

Ejemplo:

services:
  web:
    image: nginx
    deploy:
      replicas: 3
    depends_on:
      - db

Inicia 3 instancias web; solo controla el orden de inicio (no la preparación).

Comandos esenciales de Docker Compose

Comando Descripción Ejemplo de uso
docker-compose up Crea e inicia contenedores docker-compose up
docker-compose up -d Ejecuta en segundo plano docker-compose up -d
docker-compose exec Ejecuta un comando en un contenedor en ejecución docker-compose exec web bash
docker-compose build Compila/recompila imágenes docker-compose build
docker-compose down Detiene y elimina contenedores, redes, volúmenes e imágenes docker-compose down
docker-compose logs -f Muestra y sigue los registros docker-compose logs -f
docker-compose ps Lista contenedores en ejecución docker-compose ps
docker-compose run Ejecuta comandos únicos (ignora el comando del archivo Compose) docker-compose run web python manage.py migrate
docker-compose stop Detiene contenedores en ejecución (se puede reiniciar con start) docker-compose stop
docker-compose restart Reinicia servicios docker-compose restart web
docker-compose pull Descarga imágenes de servicios docker-compose pull
docker-compose rm Elimina contenedores de servicios detenidos docker-compose rm web
docker-compose config Valida y muestra el archivo Compose docker-compose config
docker-compose up --scale web=3 Inicia múltiples instancias de un servicio docker-compose up --scale web=3

Patrones comunes de Compose

  • Bases de datos con datos persistentes

    services:
      mysql:
        image: mysql
        environment:
          MYSQL_ROOT_PASSWORD: password
        volumes:
          - mysql_data:/var/lib/mysql
    
    volumes:
      mysql_data:
    

    Los datos de la BD persisten en el volumen mysql_data entre reinicios de contenedores.

  • Montaje de unión de código para desarrollo

    services:
      app:
        build: .
        volumes:
          - .:/app
    

    Edita código en vivo en el host, reflejado automáticamente en el contenedor.

Bandas útiles

  • -d: Modo despegado (ejecutar en segundo plano).
  • --build: Fuerza la recompilación de imágenes antes de iniciar.
  • --force-recreate: Recrea contenedores aunque no haya cambios.
  • --remove-orphans: Elimina contenedores no definidos en el archivo Compose.

Definición y personalización de servicios

Puedes definir y personalizar servicios, redes y volúmenes en Docker Compose aprovechando el archivo docker-compose.yml, que centraliza todas las necesidades de configuración y orquestación de tu aplicación.

  • Los services se definen bajo la clave services.
  • Cada servicio representa una configuración de contenedor, donde puedes establecer:
    • Image: Selecciona una imagen de Docker Hub u otro registro.
    • Ports: Mapea puertos de contenedor a puertos del host.
    • Variables de entorno: Pasa valores de configuración.
    • Volumes: Persiste datos o comparte archivos/carpetas con el host u otros servicios.
    • Networks: Controla a qué redes puede acceder el servicio.

Ejemplo:

services:
  web:
    image: nginx:latest
    ports:
      - "8080:80"   # Puerto 8080 del host:Puerto 80 del contenedor
    environment:
      - NGINX_HOST=localhost
    volumes:
      - web_data:/usr/share/nginx/html
    networks:
      - frontend

  db:
    image: postgres:13
    environment:
      POSTGRES_USER: admin
      POSTGRES_PASSWORD: secret
    volumes:
      - db_data:/var/lib/postgresql/data
    networks:
      - backend
  • Aquí, el servicio web usa la imagen nginx, establece una variable de entorno, adjunta un volumen, abre el puerto 80 como 8080 en el host y se conecta a la red frontend. El servicio db hace algo similar para PostgreSQL.

Personalización de redes

  • Las redes controlan qué servicios pueden comunicarse. Compose crea una red predeterminada, pero puedes definir más, especificar controladores personalizados, establecer opciones y determinar qué servicio se une a qué red para un aislamiento fino.
  • Define redes a nivel superior bajo networks, y lista qué redes debe adjuntar un servicio con la clave networks a nivel de servicio.

Ejemplo:

networks:
  frontend:
    driver: bridge
  backend:
    driver: bridge
    driver_opts:
      com.docker.network.bridge.host_binding_ipv4: "127.0.0.1"
  • Adjudica redes a servicios:
services:
  app:
    networks:
      - frontend
      - backend
  db:
    networks:
      - backend
  • Esta configuración permite que el servicio app acceda a los usuarios en las redes frontend y backend, mientras que db es accesible solo dentro de backend.

Personalización de volúmenes

  • Los volúmenes se definen bajo la clave a nivel superior volumes. Adjúntalos a contenedores usando la clave volumes bajo un servicio.
  • Los volúmenes pueden tener nombre, usar controladores personalizados y compartirse entre múltiples servicios para persistencia y compartición de datos.

Ejemplo:

volumes:
  web_data:                # Volumen con nombre para contenido web
  db_data:                 # Volumen con nombre para base de datos

services:
  web:
    volumes:
      - web_data:/usr/share/nginx/html

  db:
    volumes:
      - db_data:/var/lib/postgresql/data
  • En este ejemplo, web_data es persistente y está disponible para cualquier contenedor que lo monte. db_data asegura que los datos de la base de datos nunca se pierdan ante la recreación del contenedor.
  • Puedes definir montajes de unión con opciones de controlador personalizadas para casos avanzados:
volumes:
  db_data:
    driver: local
    driver_opts:
      type: none
      device: /data/db_data
      o: bind
  • Esta configuración establece un montaje de unión desde la ruta del host /data/db_data hacia el contenedor.

Resumen de mejores prácticas:

  • Usa el nombre del servicio como nombre de host DNS para la comunicación entre servicios.
  • Adjudica servicios a múltiples redes según sea necesario para controlar el acceso.
  • Usa volúmenes con nombre para almacenamiento persistente y compartición de datos.
  • Define todo usando YAML, habilitando el control de versiones y scripts de implementación fáciles.
  • Para la gestión y visualización de contenedores, considera Instalar Portainer en Linux.

Múltiples archivos compose

Para organizar configuraciones complejas multi-servicio en Docker Compose, puedes usar múltiples archivos compose y archivos de reemplazo, permitiendo configuraciones modulares, específicas de entorno y escalables. Así es como funciona:

  1. Estructura de archivo base y de reemplazo
  • Crea un archivo base (compose.yaml o docker-compose.yml) que contenga todas las definiciones de servicio comunes y predeterminadas.
  • Añade archivos de reemplazo específicos de entorno (p. ej., docker-compose.override.yml, docker-compose.dev.yml, docker-compose.prod.yml).

Ejemplo de estructura de archivos:

/directorio-proyecto
|-- docker-compose.yml           # Configuración base
|-- docker-compose.override.yml  # Reemplazos locales/dev (aplicados automáticamente)
|-- docker-compose.prod.yml      # Reemplazos de producción
|-- docker-compose.test.yml      # Reemplazos de prueba (si es necesario)

La configuración base define los servicios centrales, mientras que cada archivo de reemplazo personaliza la configuración para un entorno o caso específico.

  1. Cómo funcionan los reemplazos de archivos
  • Fusión: Cuando ejecutas docker compose up, Docker Compose fusiona la base con cualquier reemplazo en orden; los archivos posteriores reemplazan, extienden o añaden a la configuración de los archivos anteriores.
  • Sobrescritura de campos: Si un servicio o campo está definido en varios archivos, se usa el valor del archivo especificado por último. Los campos nuevos se añaden.

Ejemplo de fusión:

  • docker-compose.yml:
    services:
      web:
        image: myapp
        ports:
          - "8000:80"
    
  • docker-compose.override.yml:
    services:
      web:
        environment:
          - DEBUG=true
    
  • Resultado: El servicio web usa tanto la imagen y el puerto base como la variable de entorno DEBUG reemplazada.
  1. Uso de comandos para múltiples archivos
  • Comportamiento predeterminado: Si está presente, Docker Compose carga automáticamente docker-compose.override.yml junto con docker-compose.yml cuando ejecutas cualquier comando.
  • Especificación manual de archivos: Usa las banderas -f para controlar qué archivos se fusionan y en qué orden:
    docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
    
    • Esto ignora el reemplazo predeterminado y usa la configuración específica de producción.
  1. Estrategias prácticas de organización
  • Separación de entornos: Usa un archivo de reemplazo por entorno: dev, test, prod, etc.
  • Microservicios y equipos: Divide la configuración en archivos separados para diferentes servicios o equipos, y combínalos según sea necesario.
  • Conmutación de funciones: Archivos adicionales pueden introducir o eliminar servicios o configuraciones opcionales para necesidades temporales (p. ej., un compose.debug.yml para registros adicionales).
  1. Beneficios
  • Claridad: Mantiene los archivos individuales pequeños y enfocados.
  • Escalabilidad: Añade fácilmente nuevos servicios, entornos o configuraciones.
  • Mantenibilidad: Solo cambia o revisa las secciones relevantes para una implementación dada.
  1. Ejemplo: Cambio de entornos

Desarrollo:

docker compose -f docker-compose.yml -f docker-compose.dev.yml up

Producción:

docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d

Cada entorno obtiene solo la configuración necesaria para él, con toda la configuración compartida en el archivo base.

Organizar configuraciones Compose complejas con múltiples archivos - y aprovechar el sistema de reemplazo/fusión - asegura modularidad, personalización específica de entorno y escalabilidad fácil para aplicaciones Docker multi-servicio de gran tamaño.

Para despliegue en producción en un solo host Linux — arranque al iniciar, apagado limpio, actualizaciones y rotación de registros — consulta Ejecutar Docker Compose como servicio de Linux con systemd. Para una comparación con Podman Quadlet, consulta Podman Quadlet vs Docker Compose para servicios de Linux.

Enlaces útiles

Suscribirse

Recibe nuevas publicaciones sobre sistemas, infraestructura e ingeniería de IA.