环境变量注入是什么
在启动容器时用环境变量把配置交给应用,是容器化服务最常见的做法:镜像负责代码与默认值,环境相关的地址、账号、日志级别由运行时注入。可以逐个传入,也可以用文件批量注入,后者更适合变量较多的场景。
基本信息
| 单个注入 | 多次使用 -e 键=值 的形式 |
|---|---|
| 批量注入 | 用 --env-file 指定文件,文件内每行一个键值对 |
| 文件规则 | 不要写导出关键字,不要加引号,空行会被忽略 |
| 只写键名 | 表示从当前宿主环境取值,宿主没有该变量就等于没传 |
| 优先级 | 命令行传入的值覆盖镜像里声明的同名默认值 |
典型使用场景
- 区分环境:用同一个镜像跑开发、测试、生产,只改环境标识与依赖地址
- 注入连接信息:数据库地址、缓存地址、外部接口域名按部署环境替换
- 调整日志级别:排查期临时打开调试输出,事后改回常规级别
- 统一时区与编码:避免日志时间与业务时间错位、文本出现乱码
- 流水线部署:把流水线变量注入容器,实现版本号与构建信息的传递
常用示例
常用示例
docker run -d -e TZ=Asia/Shanghai -e APP_ENV=prod app/api:v1.2 # 逐个注入
docker run --rm --env-file ./app.env alpine:3.20 env | sort # 按文件注入并回显
docker inspect -f '{{json .Config.Env}}' api # 核对实际生效的变量
# app.env 文件内容示例
# TZ=Asia/Shanghai
# APP_ENV=staging
# LOG_LEVEL=info两种注入方式对照
| 对比项 | 命令行逐个传 | 按文件批量传 |
|---|---|---|
| 适合规模 | 变量少、临时调试 | 变量多、需要版本化维护 |
| 可读性 | 命令很长且容易漏 | 配置集中,便于对照评审 |
| 文件格式要求 | 键值直接写在命令行 | 每行一个键值对,不写导出关键字 |
| 版本管理 | 写在部署脚本里 | 文件可单独纳入配置管理 |
| 安全提示 | 值会出现在进程参数与对象元数据里 | 文件内容同样会进入对象元数据 |
写变量时的注意点
- 变量名大小写敏感,应用读的是哪个名字要和代码里的拼写完全一致
- 值里含空格或特殊字符要用引号包住,否则会被切成多段
- 键和值之间不要多加空格,空格会成为变量名或值的一部分
- 不要用环境变量传大段证书内容,文件挂载或密钥机制更合适
- 同一变量在镜像与环境里都定义时,以运行时注入的为准,排查时先确认来源
用环境变量传密码与令牌时,值会出现在对象元数据和容器内进程环境里,任何能查看容器配置的人都能读到。生产环境优先用挂载文件或专用的密钥机制,并限制查看权限。
只写键名不写值并不是把变量清空,而是从宿主当前环境取值;宿主没有该变量时,容器里就完全看不到这个变量,这类静默失败最难排查。
确认变量的三步核对
- 先看镜像里声明的默认值,确认不带任何注入时应用会使用什么配置
- 再看运行对象里实际注入的值,确认发布时没有漏传或传错
- 最后进容器回显一次变量,确认应用进程与脚本看到的是同一份配置
与配置管理的配合
- 环境相关值放运行时注入,业务默认值与开关放镜像内声明,边界越清楚越省事
- 变量清单要有单一出处,编排文件、部署脚本与文档共用一份来源
- 每次新增变量都要写清楚必填还是可选,缺失时的行为要能预期
- 敏感值不进版本库,用运行环境或密钥机制注入并限制查看范围
- 变更变量后要重新创建容器,已经运行的容器不会自动读取新值