Nginx原生不解析系统环境变量,配置中误用$MY_VAR会导致静默异常;Docker需依赖envsubst模板替换,且变量名须全大写、后缀为.template,否则proxy_pass等指令将失效。

Nginx 本身不支持直接读取系统环境变量(如 $PATH 或 $MY_VAR),所谓“环境变量未解析”,实际是配置中误用了环境变量语法,或在容器/模板场景下变量替换失败——这类问题不会被 nginx -t 报出语法错误,但会导致指令值为空、路径错乱、代理失效等静默异常。
确认是否真在用 Nginx 原生命令引用环境变量
Nginx 配置里写 $MY_VAR 是无效的:Nginx 只识别内置变量($host、$request_uri 等)和模块声明变量(set $x "val")。它不会自动展开 shell 或 Docker 环境变量。若你看到类似 root /var/www/$APP_ENV; 这样的写法,它不会被替换,而是字面传给文件系统,最终导致 404 或启动失败。
- 检查配置中所有带
$的地方:用grep -n '\$[A-Z_]*' /etc/nginx/conf.d/*.conf扫描,确认是否误把模板变量当成了 Nginx 变量 - 若没使用模板引擎(如 envsubst、Ansible、宝塔),那所有
$XXX都应是 Nginx 内置或显式set定义的,否则就是错的
排查 Docker 容器中 envsubst 模板替换失败
官方 Nginx Docker 镜像依赖 envsubst 在启动时处理 .template 文件。常见失败点不是语法错误,而是替换逻辑中断:
- 确保模板文件后缀是
.template,且放在/etc/nginx/templates/下(默认路径) - 检查环境变量名是否全大写、只含字母/数字/下划线;
${my_var}不合法,必须写成${MY_VAR} - 运行容器前手动测试替换:
env MY_PORT=8080 envsubst /tmp/out.conf,再用nginx -t -c /tmp/out.conf校验输出结果 - 查看容器日志:
docker logs <container></container>,正常会有Processing /etc/nginx/templates/default.conf.template日志;若无,说明模板未触发
验证最终生效的配置内容是否含预期值
即使模板渲染成功,也要确认变量是否真正落地为有效值:
- 进容器执行
nginx -T 2>/dev/null | grep -A2 -B2 'root\|proxy_pass',看关键路径或地址是否已展开(如root /var/www/prod;而非root /var/www/$ENV;) - 在
log_format中加入可疑字段,例如:log_format main '$remote_addr "$request" $status "$upstream_addr" "$http_x_forwarded_for"';,访问后查access.log,若$upstream_addr为空,说明proxy_pass后端地址未正确解析 - 对
proxy_pass使用变量时(如proxy_pass http://$BACKEND;),必须配resolver指令,否则会报 502;这不是语法错误,但属变量使用前提
检查宝塔、Nginx Proxy Manager 等可视化工具生成的配置
这类面板常通过模板拼接生成配置,变量名可能被转义错误或遗漏:
- 打开生成的站点配置文件(如
/www/server/panel/vhost/nginx/example.com.conf),搜索$,核对每个变量是否与面板设置项一一对应 - 特别注意域名、端口、PHP 版本等字段:宝塔有时会把
{{php_version}}渲染成空字符串,导致include enable-php-*.conf路径错误 - 若配置中出现
$document_root这类看似合理但 Nginx 并未定义的变量,它会被视为空,root指令就失效了











