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

Establecer, usar y gestionar variables en un archivo de Compose mediante interpolación

Un archivo de Compose puede utilizar variables para ofrecer mayor flexibilidad. Si quieres cambiar rápidamente entre etiquetas de imagen para probar múltiples versiones, o deseas ajustar un origen de volumen a tu entorno local, no necesitas editar el archivo de Compose cada vez; puedes establecer variables que inserten valores en tu archivo de Compose en tiempo de ejecución.

La interpolación también se puede utilizar para insertar valores en tu archivo de Compose en tiempo de ejecución, los cuales luego se usan para pasar variables al entorno de tu contenedor.

A continuación se muestra un ejemplo sencillo:

$ cat .env
TAG=v1.5
$ cat compose.yaml
services:
  web:
    image: "webapp:${TAG}"

Al ejecutar docker compose up, el servicio web definido en el archivo de Compose realiza la interpolación de la imagen webapp:v1.5 que se estableció en el archivo .env. Puedes verificar esto con el comando config, el cual muestra en la terminal la configuración resuelta de tu aplicación:

$ docker compose config
services:
  web:
    image: 'webapp:v1.5'

Sintaxis de interpolación

La interpolación se aplica a valores sin comillas y con comillas dobles. Se admiten expresiones tanto con llaves (${VAR}) como sin llaves ($VAR).

Para expresiones con llaves, se admiten los siguientes formatos:

  • Sustitución directa
    • ${VAR} -> valor de VAR
  • Valor por defecto
    • ${VAR:-default} -> valor de VAR si está configurada y no está vacía; de lo contrario, default
    • ${VAR-default} -> valor de VAR si está configurada; de lo contrario, default
  • Valor requerido
    • ${VAR:?error} -> valor de VAR si está configurada y no está vacía; de lo contrario, sale con un error
    • ${VAR?error} -> valor de VAR si está configurada; de lo contrario, sale con un error
  • Valor alternativo
    • ${VAR:+replacement} -> replacement si VAR está configurada y no está vacía; de lo contrario, vacío
    • ${VAR+replacement} -> replacement si VAR está configurada; de lo contrario, vacío

Para obtener más información, consulta la Interpolación en la Especificación de Compose.

Formas de establecer variables con interpolación

Docker Compose puede interpolar variables en tu archivo de Compose desde múltiples fuentes.

Ten en cuenta que cuando la misma variable es declarada por múltiples fuentes, se aplica la precedencia:

  1. Variables de tu entorno de shell
  2. Si no se define --env-file, las variables establecidas por un archivo .env en el directorio de trabajo local (PWD)
  3. Variables de un archivo configurado mediante --env-file o un archivo .env en el directorio del proyecto

Puedes verificar las variables y los valores utilizados por Compose para interpolar el modelo de Compose ejecutando docker compose config --environment.

Archivo .env

Un archivo .env en Docker Compose es un archivo de texto utilizado para definir variables que deben estar disponibles para la interpolación al ejecutar docker compose up. Este archivo normalmente contiene pares clave-valor de variables y te permite centralizar y gestionar la configuración en un solo lugar. El archivo .env resulta útil si tienes múltiples variables que necesitas almacenar.

El archivo .env es el método por defecto para establecer variables. El archivo .env debe colocarse en la raíz del directorio del proyecto junto a tu archivo compose.yaml. Para obtener más información sobre el formato de un archivo de entorno, consulta Sintaxis para archivos de entorno.

Ejemplo básico:

$ cat .env
## definir COMPOSE_DEBUG basándose en DEV_MODE, por defecto es false
COMPOSE_DEBUG=${DEV_MODE:-false}

$ cat compose.yaml
  services:
    webapp:
      image: my-webapp-image
      environment:
        - DEBUG=${COMPOSE_DEBUG}

$ DEV_MODE=true docker compose config
services:
  webapp:
    environment:
      DEBUG: "true"

Información adicional

  • Si defines una variable en tu archivo .env, puedes hacer referencia a ella directamente en tu compose.yaml mediante el atributo environment. Por ejemplo, si tu archivo .env contiene la variable de entorno DEBUG=1 y tu archivo compose.yaml se ve así:

    services:
      webapp:
        image: my-webapp-image
        environment:
          - DEBUG=${DEBUG}

    Docker Compose reemplaza ${DEBUG} con el valor del archivo .env.

    Important

    Ten en cuenta la Precedencia de las variables de entorno al utilizar variables en un archivo .env como variables de entorno en el entorno de tu contenedor.

  • Puedes colocar tu archivo .env en una ubicación distinta a la raíz del directorio de tu proyecto y luego usar la opción --env-file en la CLI para que Compose pueda acceder a él.

  • Tu archivo .env puede ser sobrescrito por otro .env si se sustituye con --env-file.

Important

La sustitución desde archivos .env es una característica de la CLI de Docker Compose.

No es compatible con Swarm al ejecutar docker stack deploy.

Sintaxis del archivo .env

Se aplican las siguientes reglas de sintaxis a los archivos de entorno:

  • Las líneas que comienzan con # se procesan como comentarios y se ignoran.

  • Las líneas en blanco se ignoran.

  • Los valores sin comillas y con comillas dobles (") tienen interpolación aplicada.

  • Cada fila representa un par clave-valor. Los valores opcionalmente pueden estar entre comillas.

  • El delimitador que separa la clave y el valor puede ser = o :.

  • Se ignoran los espacios antes y después del valor.

    • VAR=VAL -> VAL
    • VAR="VAL" -> VAL
    • VAR='VAL' -> VAL
    • VAR: VAL -> VAL
    • VAR = VAL -> VAL
  • Los comentarios en línea para valores sin comillas deben ir precedidos de un espacio.

    • VAR=VAL # comentario -> VAL
    • VAR=VAL# no es un comentario -> VAL# no es un comentario
  • Los comentarios en línea para valores entre comillas deben seguir a la comilla de cierre.

    • VAR="VAL # no es un comentario" -> VAL # no es un comentario
    • VAR="VAL" # comentario -> VAL
  • Los valores con comillas simples (') se utilizan de forma literal.

    • VAR='$OTHER' -> $OTHER
    • VAR='${OTHER}' -> ${OTHER}
  • Las comillas se pueden escapar con \.

    • VAR='Let\'s go!' -> Let's go!
    • VAR="{\"hello\": \"json\"}" -> {"hello": "json"}
  • Las secuencias de escape de shell comunes, incluyendo \n, \r, \t y \\, son compatibles en valores con comillas dobles.

    • VAR="some\tvalue" -> some value
    • VAR='some\tvalue' -> some\tvalue
    • VAR=some\tvalue -> some\tvalue
  • Los valores entre comillas simples pueden abarcar varias líneas. Ejemplo:

    KEY='SOME
    VALUE'

    Si luego ejecutas docker compose config, verás:

    environment:
      KEY: |-
        SOME
        VALUE

Sustituir con --env-file

Puedes establecer valores por defecto para múltiples variables de entorno en un archivo .env y luego pasar el archivo como argumento en la CLI.

La ventaja de este método es que puedes almacenar el archivo en cualquier lugar y nombrarlo adecuadamente, por ejemplo. Esta ruta de archivo es relativa al directorio de trabajo actual donde se ejecuta el comando de Docker Compose. El envío de la ruta del archivo se realiza mediante la opción --env-file :

$ docker compose --env-file ./config/.env.dev up

Información adicional

  • Este método resulta útil si deseas sobrescribir temporalmente un archivo .env que ya está referenciado en tu archivo compose.yaml. Por ejemplo, puedes tener diferentes archivos .env para producción (.env.prod) y pruebas (.env.test). En el siguiente ejemplo, hay dos archivos de entorno, .env y .env.dev. Ambos tienen diferentes valores establecidos para TAG.
    $ cat .env
    TAG=v1.5
    $ cat ./config/.env.dev
    TAG=v1.6
    $ cat compose.yaml
    services:
      web:
        image: "webapp:${TAG}"
    
    Si no se utiliza --env-file en la línea de comandos, el archivo .env se carga por defecto:
    $ docker compose config
    services:
      web:
        image: 'webapp:v1.5'
    
    Pasar el argumento --env-file sobrescribe la ruta de archivo por defecto:
    $ docker compose --env-file ./config/.env.dev config
    services:
      web:
        image: 'webapp:v1.6'
    
    Cuando se pasa una ruta de archivo no válida como argumento de --env-file, Compose devuelve un error:
    $ docker compose --env-file ./doesnotexist/.env.dev  config
    ERROR: Couldn't find env file: /home/user/./doesnotexist/.env.dev
    
  • Puedes utilizar múltiples opciones --env-file para especificar varios archivos de entorno, y Docker Compose los leerá en orden. Los archivos posteriores pueden sobrescribir las variables de los archivos anteriores.
    $ docker compose --env-file .env --env-file .env.override up
    
  • Puedes sobrescribir variables de entorno específicas desde la línea de comandos al iniciar contenedores.
    $ docker compose --env-file .env.dev up -e DATABASE_URL=mysql://new_user:new_password@new_db:3306/new_database
    

Archivo .env local frente al archivo .env del

Un archivo .env también se puede utilizar para declarar variables de entorno predefinidas empleadas para controlar el comportamiento de Compose y los archivos que se deben cargar.

Cuando se ejecuta sin una bandera --env-file explícita, Compose busca un archivo .env en tu directorio de trabajo (PWD) y carga los valores tanto para la autoconfiguración como para la interpolación. Si los valores en este archivo definen la variable predefinida COMPOSE_FILE, lo que resulta en que el directorio del proyecto se establezca en otra carpeta, Compose cargará un segundo archivo .env, si está presente. Este segundo archivo .env tiene una precedencia menor.

Este mecanismo permite invocar un proyecto de Compose existente con un conjunto personalizado de variables como sobrescritura, sin necesidad de pasar variables de entorno por la línea de comandos.

$ cat .env
COMPOSE_FILE=../compose.yaml
POSTGRES_VERSION=9.3

$ cat ../compose.yaml
services:
  db:
    image: "postgres:${POSTGRES_VERSION}"
$ cat ../.env
POSTGRES_VERSION=9.2

$ docker compose config
services:
  db:
    image: "postgres:9.3"

Sustituir desde la shell

Puedes utilizar las variables de entorno existentes de tu máquina host o del entorno de shell donde ejecutas los comandos de docker compose. Esto te permite inyectar dinámicamente valores en tu configuración de Docker Compose en tiempo de ejecución. Por ejemplo, supón que la shell contiene POSTGRES_VERSION=9.3 y proporcionas la siguiente configuración:

db:
  image: "postgres:${POSTGRES_VERSION}"

Al ejecutar docker compose up con esta configuración, Compose busca la variable de entorno POSTGRES_VERSION en la shell y sustituye su valor. Para este ejemplo, Compose resuelve la imagen como postgres:9.3 antes de ejecutar la configuración.

Si una variable de entorno no está configurada, Compose la sustituye por una cadena vacía. En el ejemplo anterior, si POSTGRES_VERSION no está establecida, el valor para la opción de la imagen será postgres:.

Note

postgres: no es una referencia de imagen válida. Docker espera una referencia sin etiqueta, como postgres que por defecto utiliza la imagen latest, o con una etiqueta como postgres:15.