使用插值在 Compose 文件中设置、使用和管理变量

Compose 文件可以使用变量来提供更大的灵活性。如果您想快速切换 在镜像标签之间测试多个版本,或者想要将卷源调整为本地 环境中,您无需每次都编辑 Compose 文件,只需设置在运行时将值插入到 Compose 文件中的变量即可。

插值还可用于在运行时将值插入到 Compose 文件中,然后使用该值将变量传递到容器的环境中

下面是一个简单的示例:

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

运行 时,Compose 文件中定义的服务将插入文件中设置的镜像中。您可以使用 config 命令进行验证,该命令将解析的应用程序配置打印到终端:docker compose upwebwebapp:v1.5.env

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

插值语法

插值适用于未加引号的值和双引号的值。 支持 braced () 和 unbraced () 表达式。${VAR}$VAR

对于大括号表达式,支持以下格式:

  • 直接替换
    • ${VAR}-> 值VAR
  • 默认值
    • ${VAR:-default}-> 的值(如果已设置且非空),否则VARdefault
    • ${VAR-default}-> 值(如果已设置),否则VARdefault
  • 必需的值
    • ${VAR:?error}-> 的值 if set 且非空,否则退出并显示错误VAR
    • ${VAR?error}-> 值(如果已设置),否则退出并显示错误VAR
  • 替代值
    • ${VAR:+replacement} -> replacementif 已设置且非空,否则为空VAR
    • ${VAR+replacement} -> replacementif 已设置,否则为空VAR

有关更多信息,请参阅 Compose 规范中的插

使用插值设置变量的方法

Docker Compose 可以将变量从多个来源插入到 Compose 文件中。

请注意,当同一变量由多个源声明时,优先级适用:

  1. 来自 shell 环境的变量
  2. 如果未设置,则由本地工作目录中的文件设置的变量 (--env-file.envPWD)
  3. 来自项目目录设置的文件或项目中的文件的变量--env-file.env

您可以通过运行 来检查 Compose 用于对 Compose 模型进行插值的变量和值。docker compose config --environment

.env 文件

Docker Compose 中的文件是一个文本文件,用于定义在运行时应可用于插值的变量。此文件通常包含变量的键值对,它允许您在一个位置集中和管理配置。如果您有多个需要存储的变量,该文件非常有用。.envdocker compose up.env

该文件是设置变量的默认方法。该文件应放置在项目目录的根目录中,与您的文件相邻。有关格式化环境文件的更多信息,请参阅环境文件的语法.env.envcompose.yaml

基本示例:

$ cat .env
## define COMPOSE_DEBUG based on DEV_MODE, defaults to 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"

其他信息:

  • 如果您在文件中定义了一个变量,则可以使用 environment 属性直接在 your 中引用它。例如,如果您的文件包含环境变量,并且您的文件如下所示:.envcompose.yml.envDEBUG=1compose.yml

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

    Docker Compose 将替换为文件中的值${DEBUG}.env

    重要

    在文件中使用变量作为容器环境中的环境变量时,请注意环境变量的优先级.env

  • 您可以将文件放在项目目录根目录以外的位置,然后在 CLI 中使用 --env-file 选项,以便 Compose 可以导航到该文件。.env

  • 如果--env-file 替换您的文件,则可以将其覆盖。.env.env

重要

从文件替换是 Docker Compose CLI 的一项功能。.env

运行 时,Swarm 不支持它。docker stack deploy

.env 文件语法

以下语法规则适用于环境文件:

  • 以 开头的行将作为注释处理并忽略。#
  • 空行将被忽略。
  • 未加引号和双引号的 () 值应用了插值。"
  • 每行表示一个键值对。值可以选择引用。
    • VAR=VAL -> VAL
    • VAR="VAL" -> VAL
    • VAR='VAL' -> VAL
  • 未加引号的值的内联注释前面必须有空格。
    • VAR=VAL # comment -> VAL
    • VAR=VAL# not a comment -> VAL# not a comment
  • 带引号的值的内联注释必须跟在结束引号后面。
    • VAR="VAL # not a comment" -> VAL # not a comment
    • VAR="VAL" # comment -> VAL
  • 单引号 () 值按字面意思使用。'
    • VAR='$OTHER' -> $OTHER
    • VAR='${OTHER}' -> ${OTHER}
  • 引号可以用 .\
    • VAR='Let\'s go!' -> Let's go!
    • VAR="{\"hello\": \"json\"}" -> {"hello": "json"}
  • 常见的 shell 转义序列包括 、 、 和 在双引号值中受支持。\n\r\t\\
    • VAR="some\tvalue" -> some value
    • VAR='some\tvalue' -> some\tvalue
    • VAR=some\tvalue -> some\tvalue

替换为 --env-file

您可以在文件中为多个环境变量设置默认值,然后在 CLI 中将文件作为参数传递。.env

此方法的优点是您可以将文件存储在任何位置并对其进行适当的命名,例如, 此文件路径是相对于执行 Docker Compose 命令的当前工作目录的。传递文件路径是使用以下选项完成的:--env-file

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

其他信息:

  • 如果要临时覆盖文件中已引用的文件,则此方法非常有用。例如,您可能有不同的 production ( ) 和 testing () 文件。 在以下示例中,有两个环境文件 和 .两者都为 设置了不同的值。.envcompose.yml.env.env.prod.env.test.env.env.devTAG
    $ cat .env
    TAG=v1.5
    $ cat ./config/.env.dev
    TAG=v1.6
    $ cat compose.yml
    services:
      web:
        image: "webapp:${TAG}"
    
    如果未在命令行中使用 the,则默认加载该文件:--env-file.env
    $ docker compose config
    services:
      web:
        image: 'webapp:v1.5'
    
    传递参数会覆盖默认文件路径:--env-file
    $ docker compose --env-file ./config/.env.dev config
    services:
      web:
        image: 'webapp:v1.6'
    
    当无效的文件路径作为参数传递时,Compose 会返回错误:--env-file
    $ docker compose --env-file ./doesnotexist/.env.dev  config
    ERROR: Couldn't find env file: /home/user/./doesnotexist/.env.dev
    
  • 您可以使用多个选项来指定多个环境文件,Docker Compose 会按顺序读取它们。后面的文件可以覆盖前面文件中的变量。--env-file
    $ docker compose --env-file .env --env-file .env.override up
    
  • 您可以在启动容器时从命令行覆盖特定的环境变量。
    $ docker compose --env-file .env.dev up -e DATABASE_URL=mysql://new_user:new_password@new_db:3306/new_database
    

本地 .env 文件与 .env 文件

文件还可用于声明用于控制 Compose 行为和要加载的文件的预定义环境变量.env

在没有显式标志的情况下执行时,Compose 会在工作目录 (PWD) 中搜索文件并加载值 用于自配置和插值。如果此文件中的值定义了预定义的变量,这会导致项目目录被设置为另一个文件夹, Compose 将加载第二个文件(如果存在)。第二个文件的优先级较低。--env-file.envCOMPOSE_FILE.env.env

借助此机制,您可以使用一组自定义变量作为替换来调用现有 Compose 项目,而无需通过命令行传递环境变量。

$ 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"

从 shell 中替换

您可以使用主机或执行命令的 shell 环境中的现有环境变量。这样,您就可以在运行时将值动态注入到 Docker Compose 配置中。 例如,假设 shell 包含并且您提供以下配置:docker composePOSTGRES_VERSION=9.3

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

当您使用此配置运行时,Compose 会在 shell 中查找环境变量并将其值替换为 in。在此示例中,Compose 会在运行配置之前将镜像解析到。docker compose upPOSTGRES_VERSIONpostgres:9.3

如果未设置环境变量,则 Compose 将替换为空字符串。在前面的示例中,如果未设置,则 image 选项的值为 。POSTGRES_VERSIONpostgres:

注意

postgres:不是有效的镜像引用。Docker 需要没有标签的引用(如默认为最新镜像),或者带有标签(如 .postgrespostgres:15