一、引言:一台服务器,如何托管多个网站?

在互联网早期,一个 IP 地址通常只对应一个网站。但随着成本和资源的考量,我们迫切需要一种技术,能让一台物理服务器同时为多个域名或应用提供服务

这就是 虚拟主机(Virtual Host) 技术要解决的问题。作为现代 Web 服务器的标配功能,Nginx 的虚拟主机实现得尤为优雅和高效。本文将带你彻底掌握其原理,并通过三种主流配置方式,手把手教你实现“一机多站”。

💡 核心价值
学会虚拟主机,你就掌握了低成本、高效率部署多项目的黄金技能


二、什么是 Nginx 虚拟主机?

简单来说,虚拟主机就是 Nginx 配置文件中的一个 server 块

  • 核心思想:Nginx 通过分析客户端请求中的某些特征(如域名、IP、端口),来决定将该请求交给哪个 server 块处理。
  • 最终效果:用户访问 site-a.com 看到的是网站A的内容,而访问 site-b.com 看到的则是完全不同的网站B,尽管它们运行在同一台服务器上。

虚拟主机的三大类型

类型 区分依据 应用场景
基于域名 Host 请求头中的域名 最常用,适用于所有拥有独立域名的网站。
基于端口 请求的 TCP 端口号 适用于内部系统、管理后台等无独立域名的场景。
基于IP 服务器监听的 IP 地址 适用于服务器拥有多个公网 IP 的情况(较少见)。

三、实战:三大虚拟主机配置详解

在开始之前,请确保你已安装 Nginx,并了解其基本配置结构(http 块内包含 server 块)。

方式一:基于域名的虚拟主机(最推荐)

这是互联网上最普遍的方式。它依赖于 HTTP/1.1 协议中的 Host 头。

需求:在同一台服务器上部署 www.site-a.com 和 www.site-b.com 两个网站。

步骤

  1. 创建网站目录和测试页面

    sudo mkdir -p /var/www/site-a /var/www/site-b
    echo "<h1>Welcome to Site A!</h1>" | sudo tee /var/www/site-a/index.html
    echo "<h1>Welcome to Site B!</h1>" | sudo tee /var/www/site-b/index.html
  2. 创建虚拟主机配置文件 (推荐放在 /etc/nginx/conf.d/ 目录下):

    • /etc/nginx/conf.d/site-a.conf:
      server {
          listen 80;
          server_name www.site-a.com; # 关键:匹配域名
      
          root /var/www/site-a;
          index index.html;
      }
    • /etc/nginx/conf.d/site-b.conf:
      server {
          listen 80;
          server_name www.site-b.com; # 关键:匹配另一个域名
      
          root /var/www/site-b;
          index index.html;
      }
  3. 测试与重载

    # 检查语法
    sudo nginx -t
    # 重载配置
    sudo systemctl reload nginx
  4. 本地测试(若无真实域名):
    编辑本机 hosts 文件 (C:\Windows\System32\drivers\etc\hosts 或 /etc/hosts),添加:

    your_server_ip www.site-a.com
    your_server_ip www.site-b.com

    然后在浏览器中分别访问这两个域名即可。

方式二:基于端口的虚拟主机

当没有独立域名时,可以通过不同端口来区分服务。

需求:主站运行在 80 端口,管理后台运行在 8080 端口。

配置 (/etc/nginx/conf.d/port-based.conf):

# 主站
server {
    listen 80;
    server_name localhost;

    root /var/www/main-site;
    index index.html;
}

# 管理后台
server {
    listen 8080; # 关键:监听不同端口
    server_name localhost;

    root /var/www/admin-panel;
    index index.html;
}

访问方式

  • 主站: http://your_server_ip
  • 后台: http://your_server_ip:8080

方式三:基于IP的虚拟主机

此方式要求服务器网卡绑定多个 IP 地址。

需求:IP 192.168.1.100 对应网站A,IP 192.168.1.101 对应网站B。

配置 (/etc/nginx/conf.d/ip-based.conf):

# 网站A
server {
    listen 192.168.1.100:80; # 关键:指定IP和端口
    server_name _; # 可以用下划线表示任意域名

    root /var/www/site-a;
    index index.html;
}

# 网站B
server {
    listen 192.168.1.101:80; # 关键:指定另一个IP
    server_name _;

    root /var/www/site-b;
    index index.html;
}

访问方式

  • 网站A: http://192.168.1.100
  • 网站B: http://192.168.1.101

四、关键机制:Nginx 如何选择正确的 server 块?

当你发送一个请求时,Nginx 会按照以下优先级进行匹配:

  1. 精确匹配 listen 指令:首先根据请求的 IP 和端口,找到所有监听该地址的 server 块。
  2. 匹配 server_name:在上一步筛选出的 server 块中,根据请求头中的 Host 字段进行匹配。
    • 精确匹配server_name example.com;
    • 通配符匹配server_name *.example.com; 或 server_name www.example.*;
    • 正则匹配server_name ~^(www\.)?user\d+\.com$;
  3. 默认服务器:如果没有任何 server 块能匹配,则会使用 default_server 标记的块,或者第一个定义的 server 块。

你可以通过显式设置 default_server 来捕获所有未匹配的请求,用于返回友好的错误页面或进行安全防护:

server {
    listen 80 default_server;
    return 444; # 直接关闭连接,不响应
}

五、结语

感谢您的阅读!如果你有任何疑问或想要分享的经验,请在评论区留言交流!

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐