使用自有域名amars.no时Nginx反向代理返回404错误,更换其他域名则正常
我完全理解你的困扰——明明配置看起来都没问题,换个随便什么域名都能正常工作,偏偏自己的真实域名就返回404,这确实让人摸不着头脑。咱们一步步拆解问题,找出根源:
第一步:先确认Nginx本身能正确处理你的域名请求
首先排除Nginx配置本身的问题,直接在Nginx服务器(或者容器内部)发送指定Host头的请求,验证配置是否生效:
# 在宿主机上执行,直接访问Nginx的本地IP并指定Host curl -H "Host: jenkins.amars.no" http://192.168.0.23 curl -H "Host: hub.amars.no" http://192.168.0.23
如果这两个请求能分别返回Jenkins页面和静态HTML,说明Nginx配置是完全正确的,问题出在客户端到Nginx的请求链路(比如DNS解析、Host头传递);如果还是返回404,那就要回头检查Nginx的配置细节。
第二步:排查客户端的DNS解析是否真的指向本地Nginx
虽然dig显示解析正确,但有些客户端可能存在DNS缓存、或者系统优先使用公网DNS的情况,导致请求实际发往了公网的amars.no服务器(而公网服务器没有对应路径,返回404)。
你可以在客户端执行以下命令验证:
# 查看客户端实际解析到的IP curl -v http://jenkins.amars.no
看输出里的Connected to jenkins.amars.no (xxx.xxx.xxx.xxx) port 80,确认IP是192.168.0.23。如果显示的是公网IP,说明客户端没用到你的dnsmasq服务器,需要:
- 清除客户端的DNS缓存:
- Windows:
ipconfig /flushdns - Linux:
sudo systemd-resolve --flush-caches - macOS:
sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder
- Windows:
- 检查客户端的DNS设置,确保
192.168.0.22是唯一且优先级最高的DNS服务器,没有添加其他公网DNS。
第三步:检查Nginx的访问日志,确认请求的Host头
有时候客户端发送的请求Host头可能不符合预期(比如浏览器自动补全了主域名),你可以给每个server块添加单独的日志,方便排查:
修改hub.conf:
server { listen 80; server_name hub.amars.no; access_log /var/log/nginx/hub_access.log main; # 添加这行 location / { root /usr/share/nginx/html; index index.html index.htm; } }
修改jenkins.conf:
upstream jenkins { server 192.168.0.22:8081; } server { listen 80; server_name jenkins.amars.no; access_log /var/log/nginx/jenkins_access.log main; # 添加这行 location / { proxy_pass http://jenkins; } }
重启Nginx容器后,访问一次域名,然后查看日志:
docker exec reverse cat /var/log/nginx/jenkins_access.log docker exec reverse cat /var/log/nginx/hub_access.log
看日志里的请求记录,重点关注"request"部分前面的Host是否是你预期的jenkins.amars.no或hub.amars.no。如果Host不对,说明请求没有正确携带子域名的Host头,可能是浏览器或DNS的问题。
第四步:排查Nginx的默认Server块干扰
Nginx会按照优先级匹配Server块:精确匹配>通配符匹配>默认Server。如果你的配置里存在一个listen 80 default_server;的Server块,而这个块的配置返回404,可能会导致请求没有匹配到你的子域名Server块,反而匹配了默认Server。
你可以用docker exec reverse nginx -T查看完整配置,搜索default_server,如果存在其他默认Server,要么修改你的子域名Server块添加default_server(只能有一个默认),要么删除多余的默认Server配置。
其他可能性(概率较低)
- Docker网络问题:确认Nginx容器能访问本地网络的Jenkins服务器,执行
docker exec reverse ping 192.168.0.22,能ping通则网络正常。 - 静态文件路径问题:确认
/usr/share/nginx/html/index.html存在,执行docker exec reverse ls /usr/share/nginx/html,如果文件不存在,会导致hub.amars.no返回404,但你说换域名正常,所以这个可能性很低。
按照上面的步骤排查,应该能快速定位到问题所在。我之前遇到过类似的情况,大概率是DNS缓存或者默认Server的问题,祝你顺利解决!
备注:内容来源于stack exchange,提问作者ventle

