在Web服务器管理领域,Nginx以其高性能、低资源消耗和高度的灵活性而广受欢迎,其核心功能之一便是虚拟主机,允许在一台单一的物理服务器上托管多个独立的网站,每个网站都有其独立的域名、配置和内容,这一切的实现,关键在于server_name指令的正确配置,本文将详细、系统地探讨如何通过命令行和相关配置,来设置和管理Nginx的虚拟主机名。

理解Nginx虚拟主机与server_name
Nginx中的虚拟主机概念是通过server配置块来实现的,当Nginx接收到一个HTTP请求时,它会检查请求头中的Host字段,这个字段包含了用户尝试访问的域名,Nginx会将这个Host值与所有已启用的server块中的server_name指令值进行匹配,然后选择匹配度最高的那个server块来处理该请求。
server_name指令是虚拟主机配置的灵魂,它定义了该server块响应哪些域名或主机名的请求,其匹配顺序大致如下:
- 精确匹配:查找与
Host字段完全一致的server_name。 - 通配符匹配:如果找不到精确匹配,则查找使用通配符的名称,例如
*.example.com或example.*。 - 正则表达式匹配:如果通配符也匹配不上,则查找以波浪线开头的正则表达式。
- 默认服务器:如果以上所有匹配都失败,请求将被传递给
default_server(默认服务器)处理,如果没有显式定义default_server,则Nginx会选择列在配置文件中的第一个server块作为默认。
配置虚拟主机的完整流程
假设我们要为一台服务器添加一个名为your_domain.com的网站,以下是标准的配置步骤。
第一步:创建网站目录和测试文件
为我们的新网站创建一个专用的根目录,用于存放网站文件,按照惯例,这通常在/var/www/目录下。
# 创建网站根目录 sudo mkdir -p /var/www/your_domain.com/html # 为目录设置正确的所有权,确保Nginx用户(通常是www-data)有权限访问 sudo chown -R www-data:www-data /var/www/your_domain.com/html # 创建一个简单的HTML测试页面,以便验证配置是否成功 sudo nano /var/www/your_domain.com/html/index.html
在nano编辑器中,输入以下内容并保存:
<html>
<head>
<title>Welcome to your_domain.com!</title>
</head>
<body>
<h1>Success! The your_domain.com virtual host is working!</h1>
</body>
</html>
第二步:创建Nginx虚拟主机配置文件
为了保持配置的整洁和可管理性,最佳实践是在sites-available目录中为每个网站创建一个单独的配置文件,然后通过符号链接将其启用到sites-enabled目录。
# 创建新的配置文件 sudo nano /etc/nginx/sites-available/your_domain.com.conf
第三步:编写虚拟主机配置块
在新创建的配置文件中,添加以下内容,这里的核心就是server_name指令。
server {
listen 80;
listen [::]:80;
# 关键指令:定义此虚拟主机响应的域名
server_name your_domain.com www.your_domain.com;
# 网站根目录,与第一步创建的目录对应
root /var/www/your_domain.com/html;
# 默认索引文件
index index.html index.htm index.nginx-debian.html;
location / {
try_files $uri $uri/ =404;
}
}
配置详解:
listen 80;: 监听IPv4的80端口(HTTP)。listen [::]:80;: 监听IPv6的80端口。server_name your_domain.com www.your_domain.com;: 这是核心命令,它告诉Nginx,当请求的Host头是your_domain.com或www.your_domain.com时,就使用这个server块来处理。root /var/www/your_domain.com/html;: 指定该网站的文件根目录。location / { ... }: 定义对根URL()及其所有子路径的请求处理方式。try_files指令会按顺序尝试查找文件,如果都找不到,则返回404错误。
第四步:启用虚拟主机配置
配置文件创建后,它还不会被Nginx加载,我们需要从sites-available创建一个符号链接到sites-enabled。
# 创建符号链接以启用站点 sudo ln -s /etc/nginx/sites-available/your_domain.com.conf /etc/nginx/sites-enabled/
第五步:测试并重新加载Nginx
在应用新配置之前,务必检查Nginx配置文件的语法是否有错误,这是一个避免服务中断的关键步骤。

# 测试Nginx配置语法 sudo nginx -t
如果输出显示syntax is ok和test is successful,说明配置没有问题,平滑地重新加载Nginx服务,使其应用新配置,而无需中断现有连接。
# 重新加载Nginx配置 sudo systemctl reload nginx
在浏览器中访问http://your_domain.com,你应该能看到之前创建的测试页面。
server_name指令的高级用法
除了基本的精确匹配,server_name还支持更灵活的模式。
通配符匹配
通配符可以用于域名的开头或结尾。
server_name *.your_domain.com;: 匹配所有子域名,如blog.your_domain.com,shop.your_domain.com等。server_name your_domain.*;: 匹配所有顶级域名,如your_domain.com,your_domain.org,your_domain.net等。
正则表达式匹配
以开头的server_name会被当作正则表达式处理,这提供了强大的模式匹配能力。
# 匹配所有以 .web.your_domain.com 结尾的子域名 server_name ~^(?<subdomain>.+)\.web\.your_domain\.com$;
在这个例子中,我们使用了命名捕获组(?<subdomain>.+),它可以将匹配到的子域名部分存入一个名为$subdomain的变量,后续可以在配置中使用,例如在日志文件路径中。
设置默认服务器
你可以通过在listen指令后添加default_server参数来显式定义一个默认服务器,这对于处理指向你服务器IP但未配置特定域名的请求,或者恶意请求非常有用。
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _; # 使用一个无效的域名作为占位符
root /var/www/default/html;
# ... 其他配置 ...
}
当请求的Host头不匹配任何其他已定义的server_name时,这个server块将会被调用。
下表小编总结了server_name的不同匹配方式:
| 匹配类型 | 语法示例 | 描述 |
|---|---|---|
| 精确匹配 | example.com |
完全匹配指定的主机名,优先级最高。 |
| 通配符(后缀) | *.example.com |
匹配example.com的所有子域名。 |
| 通配符(前缀) | example.* |
匹配所有以example.开头的顶级域名。 |
| 正则表达式 | ~^www\d+\.example\.com$ |
使用Perl兼容的正则表达式进行复杂匹配。 |
| 默认/捕获所有 | _ 或 default_server |
作为后备选项,处理所有未匹配的请求。 |
相关问答FAQs
问题1:我已经按照步骤修改了Nginx配置文件并保存了,但访问网站时仍然是旧的内容或者默认页面,这是为什么?

解答:这是一个非常常见的问题,通常由以下几个原因造成:
- 未重新加载Nginx:修改配置文件后,Nginx服务并不会自动应用更改,你必须运行
sudo nginx -t确认语法无误,然后运行sudo systemctl reload nginx或sudo systemctl restart nginx来使更改生效。reload是更平滑的选择,它不会断开现有的活动连接。 - 浏览器缓存:你的浏览器可能缓存了之前的页面,尝试强制刷新(通常是
Ctrl+F5或Cmd+Shift+R)或使用隐私/无痕模式访问。 - DNS缓存:本地计算机或网络中的DNS服务器可能缓存了旧的DNS记录,你可以尝试在命令行中清空本地DNS缓存(在Windows上是
ipconfig /flushdns,在macOS上是sudo dscacheutil -flushcache),或者 simply 等待缓存自动过期。 - 符号链接未创建或错误:如果你使用了
sites-available和sites-enabled的目录结构,请确保你已经从sites-available到sites-enabled创建了正确的符号链接,可以使用ls -l /etc/nginx/sites-enabled/来检查链接是否存在且指向正确的文件。
问题2:如何将所有对http://your_domain.com的访问都自动跳转到https://your_domain.com?
解答:为了实现全站HTTPS,你通常会配置两个server块,一个监听80端口(HTTP),另一个监听443端口(HTTPS),HTTP的server块唯一的目的就是执行301永久重定向。
确保你已经为your_domain.com配置了SSL证书。
修改你的HTTP配置(通常是监听80端口的那个server块),使其内容如下:
server {
listen 80;
listen [::]:80;
server_name your_domain.com www.your_domain.com;
# 执行301永久重定向到HTTPS版本
return 301 https://$host$request_uri;
}
确保你有一个独立的server块来处理HTTPS请求:
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name your_domain.com www.your_domain.com;
# SSL证书配置
ssl_certificate /path/to/your/fullchain.pem;
ssl_certificate_key /path/to/your/privkey.pem;
# ... 其他SSL安全配置 ...
root /var/www/your_domain.com/html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
这样,当用户访问http版本时,Nginx会立即返回一个301重定向响应,告诉浏览器去访问https版本,从而实现强制跳转。$host变量会自动捕获请求中的主机名(your_domain.com或www.your_domain.com),$request_uri变量会捕获请求的路径和参数,确保跳转后用户能到达他们原本想访问的页面。