Nginx中server_name仅在同端口多域名场景下参与Host头匹配,基于端口的虚拟主机靠listen指令直接路由,server_name无效且非必需;正确做法是各service独占端口,配置独立server块。

Nginx 中不能也不需要在基于端口的虚拟主机中用 server_name 做路由——因为端口本身已是路由依据,server_name 在这种场景下不参与匹配。
这是个常见误解。关键要分清:server_name 只在基于域名的虚拟主机中起作用;而基于端口的隔离,靠的是 listen 指令本身。
为什么 server_name 对端口隔离无效?
- Nginx 在收到请求时,先根据
listen(IP + 端口)找到匹配的server块; - 只有多个
server块监听同一个端口时,才会进一步用server_name匹配 Host 头; - 如果每个
server都监听不同端口(如8081、8082),那请求一到8081,就只会进入那个server,根本不会看server_name是什么。
所以你在端口配置里写 server_name localhost 或留空,只是语法允许,并非功能必需。
正确的基于端口隔离写法
每个业务独占一个端口,配置独立 server 块,放在 /etc/nginx/conf.d/ 下(如 hr-test.conf):
server {
listen 8081;
server_name localhost; # 可写可不写,建议保留便于识别
root /var/www/hr-v2.3-test;
index index.html;
location /api/ {
proxy_pass http://127.0.0.1:3001;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}再开一个:
server {
listen 8082;
server_name localhost;
root /var/www/cms-dev;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}- ✅ 两个服务互不干扰,靠端口区分;
- ✅ 不需要 DNS、不需要改 hosts;
- ✅ 内网调试、管理后台、测试环境特别适用。
注意事项
- 确保防火墙放行对应端口(如
firewall-cmd --add-port=8081/tcp --permanent); - 避免端口冲突:检查
netstat -tuln | grep :8081; -
server_name若写成具体域名(如hr.test.local),但没配 DNS 或 hosts,反而可能让浏览器报错或跳转失败——此时不如直接写localhost或留空; - 不要在一个端口上配多个
server_name来“模拟”端口路由,这违背设计逻辑,也起不到隔离效果。
不复杂但容易忽略。



















