.env文件必须严格使用KEY=VALUE格式,禁用空格、引号、export前缀和变量插值;docker run --env-file直接注入,而docker-compose的env_file仅预定义不自动注入;敏感信息严禁写入.env文件。

env-file 文件格式必须是 KEY=VALUE,不能有空格或引号
很多人写完 .env 文件后发现变量没生效,第一反应是路径错了,其实更大概率是格式不合法。Docker 的 --env-file 不支持 shell 风格的引号包裹、等号前后空格、export 前缀,也不解析变量展开(比如 HOME_DIR=${HOME} 会原样传入,不会替换)。
正确写法只有这一种:
DB_HOST=localhost DB_PORT=5432 LOG_LEVEL=debug API_TIMEOUT=3000
错误写法示例(都会导致某行被跳过或值为空):
-
DB_HOST = localhost(等号两侧有空格) -
DB_PASSWORD="secret123"(双引号会被当值的一部分) -
export DB_USER=admin(带 export 前缀) -
BASE_URL=https://$DOMAIN/api(不支持变量插值)
docker run --env-file 和 docker-compose 的 env_file 行为不同
docker run --env-file ./prod.env 是把文件里每行当作一个独立环境变量注入容器,完全不经过宿主机 shell 解析;而 docker-compose.yml 中的 env_file 字段只是“加载文件供 YAML 内部引用”,它本身不注入变量——真正注入靠的是 environment 或 ${VAR} 插值。
常见混淆点:
- 写了
env_file: [./.env]却没在environment里显式列出变量 → 容器里根本看不到这些变量 - 误以为
env_file等价于--env-file→ 实际上 Compose 的env_file更像“预定义宏”,不是运行时注入源 - 在
environment里写- DB_HOST(无等号)→ Compose 会去宿主机环境读取,不是从.env文件读
想让 .env 文件内容真正进容器,要么用 environment: ["DB_HOST=${DB_HOST}", "DB_PORT=${DB_PORT}"],要么直接删掉 env_file 改用 docker run --env-file 启动。
敏感变量别放 env-file,尤其别提交到 Git
--env-file 读的是纯文本,文件内容会完整出现在 docker inspect 的 Config.Env 字段里,也容易被日志、监控工具意外采集。生产环境的密码、密钥、OAuth token 绝对不要写进 .env 文件。
替代方案优先级建议:
- CI/CD 流水线中通过
--env动态注入(如 GitHub Actions 的 secrets) - 使用
docker secret(仅 Swarm 模式)或docker compose --file docker-compose.secrets.yml分离敏感配置 - 挂载
/run/secrets/xxx文件,由应用自行读取(比环境变量更安全)
顺带一提:.env 文件默认不被 docker build 读取——哪怕你叫它 .env,docker build 也完全无视它。构建阶段要用 ARG + --build-arg,且别传敏感值。
文件路径是相对于 docker run 执行位置,不是 Dockerfile 或 compose 目录
docker run --env-file ./config/env.prod 的 ./config/env.prod 是从当前 shell 所在目录解析的,不是从镜像内部、也不是从 docker-compose.yml 所在目录。这点和 docker-compose.yml 里的 env_file: ./config/.env 不同——后者路径才相对于 compose 文件位置。
所以如果你在项目根目录执行 docker run,但 .env 放在 deploy/ 子目录下,就必须写成 --env-file deploy/prod.env,而不是 --env-file ./prod.env(后者会找当前目录下的 prod.env)。
验证方式很简单:
docker run --rm alpine cat ./config/env.prod → 报错说明路径不对;docker run --rm -v $(pwd)/config:/mnt alpine cat /mnt/env.prod → 能输出内容才说明路径可访问。


















