docker-compose.yml 中通过 ${var_name} 占位符动态注入环境变量,需确保 .env 文件存在且格式正确、变量名大小写匹配,并用 environment 或 env_file 显式传入容器;多环境应使用 override 文件分层管理,避免硬编码。
docker-compose.yml 里怎么用环境变量填服务器地址
环境变量不是写死在 docker-compose.yml 里的,而是靠 ${var_name} 占位符动态注入。但很多人试了发现没生效——通常是因为没在启动时加载或变量名拼错。
实操要点:
-
docker-compose默认只读取当前目录下的.env文件,且该文件不能有空格、注释(#行会被忽略,但不推荐混用) - 变量名区分大小写,
SERVER_HOST和server_host是两个变量 - 如果变量来自宿主机 shell,得用
docker-compose --env-file ./my.env up显式指定,否则 shell 环境变量不会自动透传 - YAML 中的
environment:区块可以覆盖.env,但仅对当前服务生效,不影响其他服务的${}展开
示例:.env 内容为 API_HOST=api-prod.example.com,则 docker-compose.yml 中写 command: curl http://${API_HOST}/health 就能生效。
多环境配置别硬编码,用 override 文件分层
一个 docker-compose.yml 塞所有服务器配置,后期维护会崩溃。正确做法是基础配置 + 环境专属 override。
常见错误:把 staging 和 prod 的端口、镜像、健康检查全塞进一个文件,靠注释开关,结果上线时漏掉某行注释就挂了。
实操建议:
- 主文件
docker-compose.yml只定义通用结构(服务名、卷、网络),不含具体 IP、端口、镜像 tag - 按环境建
docker-compose.staging.yml和docker-compose.prod.yml,用environment:或ports:覆盖关键字段 - 启动时用
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up合并加载 - 注意 override 文件中未声明的字段不会被清空,只会叠加或替换已存在的键
比如 prod 文件里写 image: myapp:v1.2.0,而主文件里是 image: myapp:latest,最终生效的是 v1.2.0。
容器内读不到 .env 里的变量?那是没传进去
.env 文件只供 docker-compose 解析模板,它本身不进容器。很多同学以为写了 DB_HOST=xxx,容器里 echo $DB_HOST 就能输出,结果是空的。
真正让变量进容器,得靠两种方式:
- 在服务下加
environment:字段,显式列出要透传的变量,例如:- DB_HOST=${DB_HOST} - 用
env_file:挂载一个容器内可读的 env 文件(注意路径权限,且该文件格式必须是KEY=VALUE,不能带空格) - 如果用
environment:但值为空,说明.env里没定义或拼写不一致,docker-compose config可预览展开结果 - 容器启动后执行
printenv | grep DB验证是否真的传进去了
别依赖 ENV 指令在 Dockerfile 里设默认值来“兜底”,那只是构建时的值,运行时环境变量优先级更高。
生产环境别用 docker-compose up --build 自动构建
CI/CD 流水线里直接跑 docker-compose up --build 看似省事,实际埋雷:镜像没统一打 tag、构建上下文不可复现、不同机器编译结果可能不一致。
可靠的做法是把构建和部署拆开:
- CI 阶段用
docker build -t myapp:${CI_COMMIT_TAG} .打出带版本的镜像,并推到私有 registry - 部署阶段只拉镜像,靠
image: myregistry.example.com/myapp:${DEPLOY_ENV_TAG}指定,变量从外部注入 -
docker-compose.yml里永远不要出现build:,除非是本地开发调试 - 如果非要用
build:,务必配合cache_from:和target:控制层,否则每次都是全量重编
多服务器部署时,各节点拉的镜像必须完全一致,否则同一份 compose 配置在 A 机跑通,在 B 机因镜像差异失败,排查成本极高。
环境变量不是魔法,它只是字符串替换;compose 的分层合并规则很朴素,但一旦嵌套三层以上 override,docker-compose config 输出就容易看花眼。最常被忽略的,是变量作用域——.env 文件、shell 环境、compose 的 environment、容器内的 env,四者完全独立,传错了地方,再准的配置也白搭。











