机制说明
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 的那一步注入,而不是只写进了镜像构建阶段