# 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:

```console
$ 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](/compose/how-tos/environment-variables/variable-interpolation/variable-interpolation/) de la imagen `webapp:v1.5` que se estableció en el archivo `.env`. Puedes verificar esto con el [comando config](/reference/cli/docker/compose/config/), el cual muestra en la terminal la configuración resuelta de tu aplicación:

```console
$ 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](/reference/compose-file/interpolation/) 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](#env-file-syntax).

Ejemplo básico:

```console
$ 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`](/reference/compose-file/services/#environment). Por ejemplo, si tu archivo `.env` contiene la variable de entorno `DEBUG=1` y tu archivo `compose.yaml` se ve así:

  ```yaml
  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](/compose/how-tos/environment-variables/variable-interpolation/envvars-precedence/) 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](#substitute-with---env-file) para que Compose pueda acceder a él.

- Tu archivo `.env` puede ser sobrescrito por otro `.env` si se [sustituye con `--env-file`](#substitute-with---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` <!-- markdownlint-disable-line no-space-in-code -->
- 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:

  ```yaml
  KEY='SOME
  VALUE'
  ```

  Si luego ejecutas `docker compose config`, verás:

  ```yaml
  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` :

```console
$ 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`.
  ```console
  $ 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:
  ```console
  $ docker compose config
  services:
    web:
      image: 'webapp:v1.5'
  ```
  Pasar el argumento `--env-file` sobrescribe la ruta de archivo por defecto:
  ```console
  $ 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:
  ```console
  $ 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.
  ```console
  $ 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.
  ```console
  $ 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 <directorio del proyecto>

Un archivo `.env` también se puede utilizar para declarar [variables de entorno predefinidas](/compose/how-tos/environment-variables/variable-interpolation/envvars/) 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.

```console
$ 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:

```yaml
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`.

