docker compose 不自动将 .env 文件内容注入容器,而是先解析其中变量用于 docker-compose.yml 替换(如 ${db_host}),再通过 environment 或 env_file 显式传递;.env 仅参与解析,不进容器,敏感信息应避免写入 .env。

环境变量不能直接靠 .env 文件“自动进容器”——Docker 或 Docker Compose 本身不会把项目根目录下的 .env 文件内容直接注入运行中的容器。真正起作用的是“解析 + 显式传递”两步:先读取 .env 中的键值对,再通过 environment 或 env_file 字段把它们送进容器。
.env 文件只影响 Compose 解析过程,不进容器
默认情况下,Docker Compose 会读取项目根目录的 .env 文件(无需声明),但它仅用于在解析 docker-compose.yml 时做变量替换,比如:
# .env
DB_HOST=postgres
APP_ENV=staging
# docker-compose.yml
services:
web:
image: myapp
environment:
- DATABASE_URL=postgresql://${DB_HOST}/mydb
- APP_ENV=${APP_ENV}
这里 ${DB_HOST} 是被替换成 "postgres" 后,才写入 environment 列表的。最终进容器的,是替换后的字符串,不是 .env 本身。
用 environment + ${VAR} 实现变量透传
这是最常用、最清晰的方式:在 .env 中定义默认值,在 docker-compose.yml 的 environment 下引用它们。
- 支持 Shell 环境变量覆盖:在终端执行
DB_HOST=localhost docker-compose up,容器中 DB_HOST 就是 localhost,而非 .env 里的值 - 变量名需全大写,且不能含特殊字符(如 -、.)
- 引用语法必须是
${VAR_NAME},不能写成$VAR_NAME或${VAR_NAME:-default}(Compose 不支持默认值展开)
用 env_file 把变量批量加载进容器
如果你希望把 .env 或其他文件的内容原样作为环境变量注入容器(比如含密码、密钥等敏感项),就该用 env_file:
- 新建一个
prod.env,内容为:
DB_PASSWORD=secret123
REDIS_URL=redis://cache:6379 - 在服务中声明:
env_file:
- ./prod.env - 注意:
env_file加载的变量会出现在容器的env输出里;但若同时用了environment字段,它的值优先级更高,会覆盖同名变量
敏感信息别放 .env,改用运行时注入
.env 文件容易误提交到 Git,尤其含密码、Token 时。生产环境建议:
- 把敏感字段从 .env 移出,改用
docker run -e DB_PASSWORD=$(get-secret)或 CI/CD 工具拉取后注入 - 在 Docker Compose v3.1+ 中配合
secrets:使用(需 Swarm 或 Docker Desktop 支持) - 或用自定义 entrypoint 脚本,在容器启动时读取挂载的密钥文件并 export











