docker中配置环境变量的核心是运行时动态注入可变参数,避免硬编码:一、用-e key=value传单个变量,可覆盖dockerfile默认值或新增(如-e tz=asia/shanghai);二、用--env-file .env批量加载,支持注释与空行,更安全;三、应用需主动读取变量才能生效;四、禁用dockerfile中设敏感信息,注意文件权限与变量作用域。

一、运行时直接传入单个变量(-e)
适合少量、明确、非敏感的参数,比如切换环境模式或指定端口。语法简单直接:
docker run -e KEY=VALUE 配合镜像名使用,可多次叠加。
- 覆盖镜像默认值:如果 Dockerfile 里写了
ENV PORT=8080,启动时加-e PORT=3000就会生效 - 新增变量:如
-e TZ=Asia/Shanghai可解决 Java/Tomcat 容器日志时间错乱问题 - 注意大小写:
DB_HOST和db_host是两个不同变量,多数框架只认大写命名
二、批量加载变量(--env-file)
适合生产环境、多参数、含敏感信息(如密码、密钥)的场景,推荐作为标准做法。先准备一个本地 .env 文件(不提交到 Git):
NODE_ENV=production DB_HOST=db-prod.internal DB_PASSWORD=7xK!q9#mL2 API_TIMEOUT=5000
然后启动容器:
docker run --env-file .env my-app
- 文件支持
#注释和空行,但不支持变量展开(例如不能写HOME_DIR=$HOME) - 宿主机路径必须是绝对路径或当前目录下的相对路径;Docker 不会校验文件是否存在,写错路径也不会报错,只会静默忽略
- 比命令行更安全——避免密码出现在 shell 历史或进程列表中
三、配合应用逻辑动态生效
环境变量本身只是“值”,真正起作用要靠应用读取并响应它。常见配合方式:
-
Spring Boot:通过
spring.profiles.active=${SPRING_PROFILES_ACTIVE}加载对应 profile 的配置文件 -
Node.js:用
process.env.PORT启动 HTTP 服务,而不是写死3000 -
MySQL 官方镜像:识别
MYSQL_ROOT_PASSWORD、MYSQL_DATABASE等变量自动初始化 -
JVM 应用:设
JAVA_TOOL_OPTIONS="-Xmx1g -XX:+UseG1GC",所有 java 进程都会加载(慎用于生产)
四、避开几个典型坑
实际部署中,这些细节最容易导致配置“看似设了,实则没用”:
- Dockerfile 里用
ENV写密码?不行。镜像层会残留,docker history或inspect一眼可见 - 用
CMD ["node", "server.js"]启动,再想用-e NODE_ENV=dev覆盖?可以,但变量得在应用代码里主动读取,否则无意义 - 挂载了
application.yml,却还用-e SERVER_PORT=8081?没问题——只要应用同时支持 yml + 环境变量双源配置(如 Spring Boot 默认行为) - 容器内用户是
1001,但挂载的.env文件权限是600 root:root?可能读不到。建议用644并确保组/其他用户可读











