Referencia 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 trucos de Docker Compose con ejemplos anotados para ayudarte a dominar los archivos y comandos de Compose rápidamente.

Esta guía es 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 principal:

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

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

networks:          # Red personalizada
  appnet:
    driver: bridge

volumes:           # Volumen con nombre
  db_data:
  • services: Cada contenedor en tu aplicación multi-contenedor. En el ejemplo anterior tenemos dos servicios: web y db. Para operaciones de contenedores individuales, consulta la Hoja de trucos de Docker.
  • networks & volumes: Define 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 del host 8000:Puerto del contenedor 80

Expone la aplicación en el puerto 8000 del host y construye 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 utiliza un volumen con nombre persistente - db_data.

Uso de contexto de compilación y ruta del Dockerfile

Puedes construir una imagen docker bajo demanda desde el Dockerfile especificado en docker-compose.yml.

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

Compartir 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 Uso de Ejemplo
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 Construye/reconstruye 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 Ve 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 (omite el comando en el archivo Compose) docker-compose run web python manage.py migrate
docker-compose stop Detiene contenedores en ejecución (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 ve 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 DB persisten en el volumen mysql_data entre reinicios de contenedores.

  • Montaje de enlace (bind mount) 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 (Flags) útiles

  • -d: Modo desenganche (ejecutar en segundo plano).
  • --build: Fuerza la reconstrucción de imágenes antes de iniciar.
  • --force-recreate: Recrea contenedores incluso si no han cambiado.
  • --remove-orphans: Elimina contenedores no definidos en el archivo Compose.

Definir y personalizar 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 Servicios 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 del contenedor a puertos del host.
    • Environment variables: 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 del host 8080:Puerto del contenedor 80
    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 utiliza 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.

Personalizar 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"
  • Adjunta redes a servicios:
services:
  app:
    networks:
      - frontend
      - backend
  db:
    networks:
      - backend
  • Esta configuración permite que el servicio app acceda tanto a la red frontend como backend, mientras que db solo es accesible dentro de backend.

Personalizar volúmenes

  • Los Volúmenes se definen bajo la clave de nivel superior volumes. Montarlos en 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 se persiste y está disponible para cualquier contenedor que lo monte. db_data asegura que los datos de la base de datos nunca se pierdan al recrear el contenedor.
  • Puedes definir montajes de enlace (bind-mounts) 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 enlace desde la ruta del host /data/db_data dentro del contenedor.

Resumen de las mejores prácticas:

  • Usa el nombre del servicio como nombre de host DNS para la comunicación entre servicios.
  • Adjunta 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 despliegue 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 sobrescritura, lo que permite configuraciones modulares, específicas del entorno y escalables. Así es como funciona:

  1. Estructura de archivo base y de sobrescritura
  • Crea un archivo base (compose.yaml o docker-compose.yml) que contenga todas las definiciones de servicio comunes y predeterminadas.
  • Agrega archivos de sobrescritura específicos del entorno (por ejemplo, docker-compose.override.yml, docker-compose.dev.yml, docker-compose.prod.yml).

Ejemplo de estructura de archivos:

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

La configuración base define los servicios principales, mientras que cada sobrescritura personaliza la configuración para un entorno o caso específico.

  1. Cómo funcionan las sobrescrituras de archivos
  • Fusión: Cuando ejecutas docker compose up, Docker Compose fusiona la base con cualquier sobrescritura en orden; los archivos posteriores sobrescriben, extienden o agregan configuraciones de archivos anteriores.
  • Sobrescritura de campos: Si un servicio o campo se define en múltiples archivos, se usa el valor del archivo especificado último. Se agregan nuevos campos.

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 base y el puerto como la variable de entorno DEBUG sobrescrita.
  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 la sobrescritura predeterminada y usa las configuraciones específicas de producción.
  1. Estrategias prácticas de organización
  • Separación de entornos: Usa una sobrescritura 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.
  • Interruptores de características: Archivos adicionales pueden introducir o eliminar servicios opcionales o configuraciones para necesidades temporales (por ejemplo, un compose.debug.yml para registros adicionales).
  1. Beneficios
  • Claridad: Mantiene los archivos individuales pequeños y enfocados.
  • Escalabilidad: Agrega fácilmente nuevos servicios, entornos o configuraciones.
  • Mantenibilidad: Cambia o revisa solo las secciones relevantes para un despliegue dado.
  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 complejas de Compose con múltiples archivos, y aprovechar el sistema de sobrescritura/fusión, asegura modularidad, personalización específica del entorno y escalabilidad fácil para grandes aplicaciones Docker multi-servicio.

Para el despliegue en producción en un único host Linux — arranque al inicio, apagado limpio, actualizaciones y rotación de registros — consulta Ejecutar Docker Compose como servicio de Linux con systemd.

Enlaces útiles

Suscribirse

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