Nginx index转发导致首页无法访问

这两天在部署短链接服务,配置 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,它只会告诉你匹配到第一条规则了,但实际后面还有更多的动作,结果就是在这个工具里看到的结果与实际验证不一致,被这个点误导了很久。

参考

Nginx location match tester

一文理清 nginx 中的 location 配置(系列一)

nginx中的index配置