Compartir comentarios
Las respuestas se generan en base a la documentación.

Fusionar archivos de Compose

Docker Compose permite fusionar y sobrescribir un conjunto de archivos de Compose para crear un archivo de Compose compuesto.

Por defecto, Compose lee dos archivos: compose.yaml y un archivo opcional compose.override.yaml. Por convención, el compose.yaml contiene tu configuración base. El archivo de sobrescritura puede contener sobrescrituras de configuración para servicios existentes o servicios completamente nuevos.

Si un servicio está definido en ambos archivos, Compose fusiona las configuraciones utilizando las reglas descritas a continuación y en la Especificación de Compose.

Cómo fusionar múltiples archivos de Compose

Para utilizar múltiples archivos de sobrescritura, o un archivo de sobrescritura con un nombre diferente, puedes usar la variable de entorno predefinida COMPOSE_FILE o emplear la opción -f para especificar la lista de archivos.

Compose fusiona los archivos en el orden en que se se especifican en la línea de comandos. Los archivos posteriores pueden fusionar, sobrescribir o añadir opciones a sus predecesores.

Por ejemplo:

$ docker compose -f compose.yaml -f compose.admin.yaml run backup_db

El archivo compose.yaml podría especificar un servicio webapp.

webapp:
  image: examples/web
  ports:
    - "8000:8000"
  volumes:
    - "/data"

El archivo compose.admin.yaml también puede especificar este mismo servicio:

webapp:
  environment:
    - DEBUG=1

Cualquier campo coincidente sobrescribe el archivo anterior. Los nuevos valores se añaden a la configuración del servicio webapp:

webapp:
  image: examples/web
  ports:
    - "8000:8000"
  volumes:
    - "/data"
  environment:
    - DEBUG=1

Reglas de fusión

  • Las rutas se evalúan en relación con el archivo base. Cuando utilizas múltiples archivos de Compose, debes asegurarte de que todas las rutas en los archivos sean relativas al archivo de Compose base (el primer archivo de Compose especificado con -f). Esto es necesario porque los archivos de sobrescritura no tienen por qué ser archivos de Compose válidos. Los archivos de sobrescritura pueden contener pequeños fragmentos de configuración. Realizar el seguimiento de qué fragmento de un servicio es relativo a qué ruta es difícil y confuso, por lo que para mantener las rutas más fáciles de entender, todas deben definirse en relación con el archivo base.

    Tip

    Puedes utilizar docker compose config para revisar tu configuración fusionada y evitar problemas relacionados con las rutas.

  • Compose copia las configuraciones del servicio original al local. Si se define una opción de configuración tanto en el servicio original como en el servicio local, el valor local reemplaza o extiende el valor original.

    • Para opciones de valor único como image, command o mem_limit, el nuevo valor reemplaza al valor anterior.

      servicio original:

      services:
        myservice:
          # ...
          command: python app.py

      servicio local:

      services:
        myservice:
          # ...
          command: python otherapp.py

      resultado:

      services:
        myservice:
          # ...
          command: python otherapp.py
    • Para las opciones de múltiples valores ports, expose, external_links, dns, dns_search y tmpfs, Compose concatena ambos conjuntos de valores:

      servicio original:

      services:
        myservice:
          # ...
          expose:
            - "3000"

      servicio local:

      services:
        myservice:
          # ...
          expose:
            - "4000"
            - "5000"

      resultado:

      services:
        myservice:
          # ...
          expose:
            - "3000"
            - "4000"
            - "5000"
    • En el caso de environment, labels, volumes y devices, Compose "fusiona" las entradas, teniendo precedencia los valores definidos localmente. Para environment y labels, la variable de entorno o el nombre de la etiqueta determina qué valor se utiliza:

      servicio original:

      services:
        myservice:
          # ...
          environment:
            - FOO=original
            - BAR=original

      servicio local:

      services:
        myservice:
          # ...
          environment:
            - BAR=local
            - BAZ=local

      resultado:

      services:
        myservice:
          # ...
          environment:
            - FOO=original
            - BAR=local
            - BAZ=local
    • Las entradas de volumes y devices se fusionan utilizando la ruta de montaje en el contenedor:

      servicio original:

      services:
        myservice:
          # ...
          volumes:
            - ./original:/foo
            - ./original:/bar

      servicio local:

      services:
        myservice:
          # ...
          volumes:
            - ./local:/bar
            - ./local:/baz

      resultado:

      services:
        myservice:
          # ...
          volumes:
            - ./original:/foo
            - ./local:/bar
            - ./local:/baz

Para obtener más reglas de fusión, consulta Fusionar y sobrescribir (Merge and override) en la Especificación de Compose.

Información adicional

  • El uso de -f es opcional. Si no se proporciona, Compose busca en el directorio de trabajo y en sus directorios padre un archivo compose.yaml y un archivo compose.override.yaml. Debes proporcionar al menos el archivo compose.yaml. Si ambos archivos existen en el mismo nivel de directorio, Compose los combina en una sola configuración.

  • Puedes utilizar -f con - (guion) como nombre de archivo para leer la configuración desde la entrada estándar (stdin). Por ejemplo:

    $ docker compose -f - <<EOF
      webapp:
        image: examples/web
        ports:
         - "8000:8000"
        volumes:
         - "/data"
        environment:
         - DEBUG=1
      EOF
    

    Cuando se utiliza stdin, todas las rutas en la configuración son relativas al directorio de trabajo actual.

  • Puedes utilizar la bandera -f para especificar una ruta a un archivo de Compose que no se encuentra en el directorio actual, ya sea desde la línea de comandos o configurando la variable de entorno COMPOSE_FILE en tu shell o en un archivo de entorno.

    Por ejemplo, si estás ejecutando el ejemplo de Compose Rails y tienes un archivo compose.yaml en un directorio llamado sandbox/rails. Puedes utilizar un comando como docker compose pull para obtener la imagen de postgres para el servicio db desde cualquier lugar utilizando la bandera -f de la siguiente manera: docker compose -f ~/sandbox/rails/compose.yaml pull db

    Aquí está el ejemplo completo:

    $ docker compose -f ~/sandbox/rails/compose.yaml pull db
    Pulling db (postgres:18)...
    18: Pulling from library/postgres
    ef0380f84d05: Pull complete
    50cf91dc1db8: Pull complete
    d3add4cd115c: Pull complete
    467830d8a616: Pull complete
    089b9db7dc57: Pull complete
    6fba0a36935c: Pull complete
    81ef0e73c953: Pull complete
    338a6c4894dc: Pull complete
    15853f32f67c: Pull complete
    044c83d92898: Pull complete
    17301519f133: Pull complete
    dcca70822752: Pull complete
    cecf11b8ccf3: Pull complete
    Digest: sha256:1364924c753d5ff7e2260cd34dc4ba05ebd40ee8193391220be0f9901d4e1651
    Status: Downloaded newer image for postgres:18
    

Ejemplo

Un caso de uso común para múltiples archivos es cambiar una aplicación de Compose de desarrollo para un entorno similar al de producción (que puede ser producción, staging o CI). Para admitir estas diferencias, puedes dividir tu configuración de Compose en varios archivos diferentes:

Comienza con un archivo base que defina la configuración canónica para los servicios.

compose.yaml

services:
  web:
    image: example/my_web_app:latest
    depends_on:
      - db
      - cache

  db:
    image: postgres:18

  cache:
    image: redis:latest

En este ejemplo, la configuración de desarrollo expone algunos puertos al host, monta nuestro código como un volumen y compila la imagen web.

compose.override.yaml

services:
  web:
    build: .
    volumes:
      - ".:/code"
    ports:
      - 8883:80
    environment:
      DEBUG: "true"

  db:
    command: "-d"
    ports:
      - 5432:5432

  cache:
    ports:
      - 6379:6379

Al ejecutar docker compose up, este lee las sobrescrituras automáticamente.

Para usar esta aplicación de Compose en un entorno de producción, se crea otro archivo de sobrescritura, que podría almacenarse en un repositorio de git diferente o ser gestionado por un equipo distinto.

compose.prod.yaml

services:
  web:
    ports:
      - 80:80
    environment:
      PRODUCTION: "true"

  cache:
    environment:
      TTL: "500"

Para realizar el despliegue con este archivo de Compose de producción, puedes ejecutar:

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

Esto despliega los tres servicios utilizando la configuración en compose.yaml y compose.prod.yaml, pero no la configuración de desarrollo en compose.override.yaml.

Para obtener más información, consulta Usar Compose en producción.

Limitaciones

Docker Compose admite rutas relativas para los diversos recursos que se incluirán en el modelo de la aplicación: contexto de compilación para las imágenes de los servicios, ubicación del archivo que define las variables de entorno, ruta a un directorio local utilizado en un volumen montado por vinculación (bind-mount). Con tal restricción, la organización del código en un monorepositorio puede volverse difícil, ya que una opción natural sería tener carpetas dedicadas por equipo o componente, pero entonces las rutas relativas de los archivos de Compose pierden sentido.

Información de referencia