env指令仅在nginx main块中声明环境变量白名单,供worker进程继承,不支持赋值或嵌套;变量需先注入主进程,再通过lua的os.getenv()或perl的$env{}读取并转为nginx变量使用。

env 指令本身不“传递”变量,它只在 Nginx 启动时控制哪些系统环境变量能被 worker 进程继承。真正把变量用起来,得靠后端脚本(如 Lua 或 Perl)主动读取,再结合 Nginx 配置做转换。整个过程分三步:注入、放行、读取使用。
确保变量已真实注入到 Nginx 主进程环境
env 指令生效的前提是变量必须已在操作系统层面存在,并被带入 Nginx 主进程空间。常见方式包括:
- Docker 启动时用 -e APP_ENV=staging 显式传入
- Kubernetes 中通过 env: 或 envFrom: 注入容器
- 宿主机启动前用 export 设置,再运行 nginx(需确认 nginx 是该 shell 的子进程)
验证是否成功:进容器执行 ps auxf | grep nginx 找主进程 PID,再运行 cat /proc/
在 nginx.conf 最外层声明 env 白名单
env 指令只能写在 main 上下文(即 events 块之前、http 块之外的顶层位置),每行一个变量名,不支持赋值或嵌套:
- ✅ 正确:env APP_ENV; env API_HOST;
- ❌ 错误:env APP_ENV=staging;(不能赋值)、env *;(不支持通配符)、放在 http 块内(语法报错)
留空写 env; 会放行全部变量,但生产环境不建议,有安全风险。
在 Lua 或 Perl 脚本中读取并转为 Nginx 变量
env 放行后,变量进入 worker 进程环境,但 Nginx 配置本身仍不能直接引用(比如不能写 proxy_pass http://$API_HOST)。必须借助运行时模块将其提取为 Nginx 内部变量:
- Lua 场景:用 set_by_lua_block 调 os.getenv("APP_ENV") or "production",生成 $app_env 变量,再用于 proxy_set_header 或 add_header
- Perl 场景:用 perl_set $api_host 'sub { return $ENV{"API_HOST"} || "https://default.example.com"; }'
- Nginx 1.19+ 原生支持 $ENV{VAR}:仅限日志格式、add_header、return 等少数上下文,不能用于 root、proxy_pass 等指令参数直用位置
注意变量使用的上下文限制
不是所有地方都能用环境变量值:
- ✅ 可用:log_format、add_header、return 中的响应体、set_by_lua_block 返回值
- ❌ 不可用:root、proxy_pass、include、if 条件判断等静态解析位置——这些需要提前确定路径或地址,不能依赖运行时值
若需动态路由或文件路径,必须走 Lua/Perl + set_by_lua_block + 变量插值组合方案。











