首页/云/Docker 容器速查/compose 变量插值语法与转义
Compose 编排55 条

compose 变量插值语法与转义

文件值里的 ${VAR} 在解析阶段被替换:支持 :- 默认值与 :? 必填校验,字面量美元符要写 $$。

Docker 容器速查云更新于 2026-10-13

机制说明

Compose 在解析阶段先对文件里的字符串做变量替换,语法是 ${VAR} 或 $VAR,并支持默认值 ${VAR:-default}、必填校验 ${VAR:?message} 等修饰。想在文件里保留一个字面美元符要写成 $$。替换发生在 Compose 读取文件时,容器里看到的已经是替换后的结果,与容器内的 shell 变量没有关系。

基本信息

基本引用${VAR} 或 $VAR
默认值${VAR:-default}
必填校验${VAR:?message},未设置即报错退出
转义$$ 输出单个美元符
取值来源shell 环境变量、同目录 .env、--env-file 指定的文件

典型使用场景

  • 同一份 compose 文件在开发、测试、生产使用不同镜像标签
  • 镜像仓库地址按环境切换,避免手工改文件
  • 密码与令牌用必填语法强制外部注入,防止默认值进仓库
  • 传入容器内的 shell 片段需要保留 $ 变量时用 $$ 转义
  • CI 里通过环境变量注入版本号与构建号

插值写法

插值写法
services:
  api:
    image: app/api:${TAG:-latest}          # 未设置 TAG 时取 latest
    environment:
      DB_HOST: ${DB_HOST:-db}
      DB_PASSWORD: ${DB_PASSWORD:?必须在环境中提供 DB_PASSWORD}
      SHELL_SNIPPET: 'echo $$HOSTNAME'     # $$ 转义,容器内看到 echo $HOSTNAME

确认最终取值

确认最终取值
TAG=1.4.2 docker compose config        # 打印替换后的最终配置
docker compose config --environment    # 列出当前生效的变量
printf 'TAG=1.4.2\n' > .env            # 同目录 .env 会被自动读取
docker compose --env-file .env.prod config   # 显式指定变量文件

语法对照

写法含义示例
${VAR}取变量值,未定义时为空image: app/api:${TAG}
${VAR:-default}未设置时用默认值${TAG:-latest}
${VAR:?message}未设置时报错退出${DB_PASSWORD:?必须提供}
$$转义为单个美元符command 里的 shell 变量
shell 环境变量的优先级高于 .env 文件;怀疑变量没生效时,先用 docker compose config 打印最终配置,比逐个猜测更可靠。
.env 只在项目目录被自动读取,其他路径要用 --env-file 指定;该文件通常包含敏感值,不要提交到仓库。

插值不生效的排查

  • 先用 docker compose config 看替换后的最终值,而不是直接看源文件
  • 确认变量来源:shell 环境变量优先,其次才是同目录 .env
  • 检查文件里是否误用了单引号包裹需要插值的片段
  • CI 里确认变量是在执行 compose 的那一步注入,而不是只写进了镜像构建阶段

易错点

  • shell 命令里想保留 $ 却忘了用 $$ 转义:变量在 Compose 解析阶段就被替换,容器里拿到的是空值或错值
  • 把密钥作为默认值写进 compose 文件:文件提交即等于泄露,敏感项应统一用必填语法强制外部注入
  • 依赖 .env 却没确认加载路径:换个目录执行就取不到变量,同一份文件在不同机器上行为不一致
  • 改了环境变量却没重建容器:环境变量在创建时写入,必须执行 up -d 重建才生效

数据来源与参考

  • Docker 官方文档:Compose 变量插值(docs.docker.com/compose/environment-variables/variable-interpolation)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌