env指令仅在nginx main块中声明环境变量白名单,供lua(os.getenv)或perl($env{})模块读取,不支持嵌套块、赋值、通配符,且启动后变量变更需reload生效。

env 指令本身不能直接“传递”变量给 Lua 或 Perl 脚本,它只在 Nginx 主配置的全局块(main 块)中起白名单作用:允许指定的系统环境变量被继承进 Nginx 进程空间,供后续模块(如 ngx_http_lua_module 或 ngx_http_perl_module)读取。真正完成“读取并使用”的是 Lua 或 Perl 模块自身的代码逻辑。
在 main 块中用 env 指令声明白名单
Nginx 默认会过滤掉大部分操作系统环境变量,以增强安全性。若想让某个变量(如 DEPLOY_STAGE、BACKEND_HOST)能在 Lua 或 Perl 中访问,必须先在 main 块(即 nginx.conf 顶层,不在 http 或 server 内)显式声明:
-
✅ 正确写法(放在最外层):
env DEPLOY_STAGE;<br>env BACKEND_HOST;
-
❌ 错误写法(放在 http 块内或注释后):
env 指令不支持出现在 http/server/location 等嵌套块中;也不支持带等号赋值(如env DEPLOY_STAGE=prod),它只做“放行”,不设值。 - 多个变量每行一个;若留空(
env;),则允许全部环境变量——但生产环境不推荐。
在 Lua 脚本中安全读取已放行的变量
前提:已编译启用 ngx_http_lua_module,且 main 块中已放行对应变量(如 env DEPLOY_STAGE;)。Lua 侧通过 os.getenv() 获取,建议加默认值防空:
- 在 http 块中定义变量:
set_by_lua_block $deploy_stage { return os.getenv("DEPLOY_STAGE") or "production" }; - 在 location 中使用:
proxy_set_header X-Deploy-Stage $deploy_stage;<br>proxy_pass http://$backend_host;
(若 backend_host 也已放行) - 注意:
os.getenv()返回字符串,需手动转换类型(如tonumber(os.getenv("PORT")))
在 Perl 脚本中读取已放行的变量
前提:已启用 ngx_http_perl_module,且 main 块中已放行(如 env LOG_LEVEL;)。Perl 侧通过 $ENV{} 访问:
- 在 http 块中定义变量:
perl_set $log_level 'sub { return $ENV{"LOG_LEVEL"} || "warn"; }'; - 在日志或响应中使用:
error_log /var/log/nginx/app.log $log_level;<br>add_header X-Log-Level $log_level;
- Perl 变量名区分大小写,
$ENV{"LOG_LEVEL"}和$ENV{"log_level"}是不同变量
关键注意事项
- Nginx 启动时读取一次环境变量,运行中修改系统变量(如
export DEPLOY_STAGE=staging)不会自动生效,需 reload 或 restart Nginx - env 指令不支持通配符(如
env DEPLOY_*),必须逐个列出 - 若变量含空格或特殊字符,Nginx 无法解析,建议只用于简单标识类变量(stage、region、version)
- Perl 模块使用较少,稳定性与性能不如 Lua,新项目优先选 Lua 方案











