Nginx 配置格式化
按 { } 与 ; 换行缩进,梳理 conf 配置层级
Nginx 配置格式化:括号陷阱与格式化不等于校验
Nginx 配置的语法结构
Nginx 配置的语法很简洁,只有几条规则:
| 元素 | 写法 |
|---|---|
| 简单指令 | directive 参数1 参数2; —— 以分号结尾 |
| 块指令 | directive { ... } —— 花括号包裹,后面不需要分号 |
| 注释 | # 到行尾 |
| 变量 | $variable,如 $host $request_uri $1(正则捕获) |
| 包含 | include /etc/nginx/conf.d/*.conf; |
格式化就是按花括号层级缩进、按分号换行。看起来简单,但有几个真实的坑。
坑一:字符串与正则里的花括号
格式化器按花括号计数来判断层级,但花括号可能出现在引号包裹的字符串或正则表达式里:
- 正则里的量词:
location ~ ^/api/v[0-9]{2}/ { ... }——{2}会被误判为一个块的开始,导致后续所有缩进错位。 - 配置值里的花括号:
add_header X-Thing "a{b}c";—— 引号内的花括号不该参与层级计算。 - 变量与占位符:
try_files $uri $uri/ /index.html;里的$uri这类写法必须原样保留。
一个健壮的实现必须先跳过引号包裹的内容,并识别正则所在的上下文。如果格式化后缩进突然"越来越深",多半是某个正则里的花括号被当成了块。工具在计数时会跳过字符串与注释中的花括号。
坑二:格式化不等于校验
这是最重要的一条使用纪律。格式化只调整空白,不会发现配置错误:
| 错误类型 | 格式化能否发现 |
|---|---|
| 缺少分号 | 不能。格式化后依然缺分号,nginx 启动会报错 |
拼错指令名(proxy_pas) | 不能。格式化后依然拼错 |
| 花括号不配对 | 可能表现为缩进异常,但工具不一定报错 |
| 指令放在了不合法的作用域 | 不能。这需要理解 nginx 的配置继承规则 |
正确做法是:格式化之后用 nginx -t 检查语法(需要 nginx 环境),或者把配置放到测试实例里 reload 验证。生产环境改配置前必须走这一步——nginx 的 reload 是平滑的,但如果配置有语法错误,新进程起不来而旧进程仍在服务,你会以为修改生效了,实际没有。
配置的可读性约定
| 建议 | 理由 |
|---|---|
| 每个 server 块前加注释说明域名或用途 | 一个站点上常有多个 server,靠 listen 和 server_name 辨认很费时 |
| location 顺序按具体到通用排列 | nginx 的前缀匹配遵循最长匹配优先,不是书写顺序;但把具体规则写前面便于人工阅读 |
| 把公共配置抽到 include 文件 | SSL 参数、日志格式、安全头这类配置在多个 server 间重复,抽出来才能统一维护 |
| 缩进用 4 空格 | nginx 官方示例用 4 空格;混用制表符会让 diff 混乱 |
第二行涉及一个容易搞错的规则:location 的匹配优先级由修饰符和匹配长度决定,不由书写顺序决定。精确匹配 = 优先,其次是最长的前缀匹配,然后是正则匹配(按书写顺序取第一个命中的)。所以把 / 写在前面不会让它优先。
工具怎么用
粘贴 nginx 配置,点格式化,按 { } 与 ; 重新换行缩进,字符串与注释中的花括号不会被误算。适合整理从服务器上复制来的压缩配置、对比两个环境的差异、以及在评审前统一格式。
处理在浏览器本地完成,配置里的域名、后端地址、路径不会上传。改完记得用 nginx -t 验证再 reload。
常见问题
引号里的内容会被误拆吗?
不会。双引号与单引号内的内容会被整体保留,不会因为里面的 ; 或 { 错误换行。
支持 if / upstream 等块吗?
支持。任何用 { } 包裹的块都会正确缩进,与官方配置层级一致。