这两天在部署短链接服务,配置 nginx 规则卡了一晚上,特此记录一下。
Nginx 配置及现象
我的需求是如果访问域名,那么直接展示首页,如果访问其他路径,则转发到后端服务。conf.d/default.conf 文件内容如下:
server {
listen 80;
listen [::]:80;
server_name localhost;
#access_log /var/log/nginx/host.access.log main;
location = / {
root /usr/share/nginx/html;
index index.html;
}
location / {
proxy_pass http://192.168.0.10:8000;
}
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
根据 nginx 中 = 精确匹配的优先级最好的原则,直接访问域名会匹配到第一个规则。但是实际上请求还是会被转发到后端,非常困惑。
途中发现一个很好用的 nginx 规则验证工具:Nginx location match tester 。每次修改规则之后要重启,再发起请求然后看结果来验证配置是否符合预期,非常繁琐,这个工具网站可以省去这些步骤,极大的提高效率。
问题和解决方案
今天上午认真的读了一篇写得挺不错的 nginx 配置教程:一文理清 nginx 中的 location 配置(系列一),在文章下的评论中看到有人贴出了自己遇到的问题,配置以及问题描述都和我遇到的问题一致,原来是 index 转发的问题。
如下配置,访问网站根目录并没有正常显示,而是返回了 404:
location = / {
index index.html;
}
location / {
return 404;
}
苏凡:@诚先森 了解下 index 指令,请求被内部重定向到第二个 location 了
回复 2022-09-16
直接访问域名 http://localhost,会匹配到第一个规则,但是 index 指令并不是找到文件之后就直接用了,而是会重新发起内部重定向,相当于从客户端发起 http://localhost/index.html ,所以会再一次匹配 location 配置。
知道原因之后就简单了,在配置中增加配置 location = /index.html 让 nginx 内部重定向到首页就好了:
server {
listen 80;
listen [::]:80;
server_name localhost;
#access_log /var/log/nginx/host.access.log main;
location = / {
root /usr/share/nginx/html;
index index.html;
}
location = /index.html {
root /usr/share/nginx/html;
}
location / {
proxy_pass http://192.168.0.10:8000;
}
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
重启 nginx 之后,就能实现直接访问域名展示首页,其余请求转发至后端服务了。
不得不提一点,Nginx location match tester 这个工具无法看出被转发的情况,比如上面的 index,它只会告诉你匹配到第一条规则了,但实际后面还有更多的动作,结果就是在这个工具里看到的结果与实际验证不一致,被这个点误导了很久。