微信优化

weixinyouhua

nginx虚拟主机配置怎么做,nginx虚拟主机配置方法有哪些

2026-11-07 03:43:36

nginx虚拟主机配置的核心答案很简单:通过server块区分不同域名或端口,实现一台服务器托管多个网站。 你只需要在配置文件中定义多个server,分别指定server_name和root,再执行nginx -t校验和reload重载即可生效。

nginx虚拟主机配置怎么做,nginx虚拟主机配置方法有哪些

nginx的灵活性和高性能让它占据了Web服务器市场的相当大份额,对于站长和运维人员来说,虚拟主机配置是必会的基本功,也是很多朋友遇到困惑较多的地方,今天咱们就抛开那些绕口的官方文档,用大白话把这件事彻底捋清楚,让你看完就能动手操作。

nginx虚拟主机配置逻辑:先理解配置文件在忙什么

想要配置得心应手,你得先知道nginx是怎么“思考”的。本质上,nginx虚拟主机配置就是定义“当用户访问特定域名时,应该把请求交给哪个目录或服务处理”的规则集合。

配置文件的骨架结构

nginx的主配置文件通常是/etc/nginx/nginx.conf(CentOS/RHEL系)或/etc/nginx/sites-available/(Ubuntu/Debian系),主配置文件里有一行关键指令:

http {
    include /etc/nginx/conf.d/.conf;
    # 或者
    # include /etc/nginx/sites-enabled/;
}

这行include就是“收纳盒”,它会把conf.d目录下所有以.conf结尾的文件都加载进来。行业共识认为,把每个虚拟主机的配置单独放在一个文件里,是维护效率最高的方式。

server块的三个核心要素

每个虚拟主机配置的核心就是server块,一个server块就是一个虚拟主机,一个最小的server块长这样:

server {
    listen 80;
    server_name example.com www.example.com;
    root /var/www/example;
    index index.html;
}

这里面的listen和server_name,就是nginx用来区分不同虚拟主机的“身份证”,当请求到达时,nginx会根据端口和域名,匹配到对应的server块。

实战指南:手把手配置基于域名的虚拟主机

基于域名的虚拟主机是最常用的场景,也就是一个IP地址上挂多个域名,下面用一个具体场景来演示。

假设你现在有两台“网站”,都跑在同一台服务器上:

  • 站点A:blog.example.com,代码放在/var/www/blog
  • 站点B:shop.example.com,代码放在/var/www/shop

第一步:创建目录结构和测试文件

先在服务器上执行命令:

mkdir -p /var/www/blog /var/www/shop
echo "<h1>这是博客</h1>" > /var/www/blog/index.html
echo "<h1>这是商城</h1>" > /var/www/shop/index.html

第二步:编写虚拟主机配置文件

在/etc/nginx/conf.d/目录下创建两个配置文件,命名要见名知意,比如blog.conf和shop.conf。

blog.conf

server {
    listen 80;
    server_name blog.example.com;
    root /var/www/blog;
    index index.html;
}

shop.conf

server {
    listen 80;
    server_name shop.example.com;
    root /var/www/shop;
    index index.html;
}

第三步:校验并重载配置

这一步非常关键,很多配置“不生效”的故障就是跳过了校验步骤。

nginx -t

如果输出syntax is ok和test is successful,说明配置格式没问题,然后执行:

nginx -s reload

reload是平滑重载,不会中断现有连接,这一点比Apache的restart要体贴得多。

第四步:验证结果

在你本地的/etc/hosts文件里临时加上解析记录(或者直接用已经解析好的域名),然后访问blog.example.com和shop.example.com,能看到各自不同的页面,就代表虚拟主机配置成功了。

nginx虚拟主机配置怎么做,nginx虚拟主机配置方法有哪些

破解默认虚拟主机与server_name匹配规则

在实际运维中,nginx服务器往往面临大量不同来源的访问请求,这些请求的Host头五花八门,理解nginx的匹配优先级能帮你避免不少坑。

当访问的域名没配置时会发生什么?

如果你访问的域名在服务器上没有对应的server块,nginx会使用默认虚拟主机来处理,默认虚拟主机就是listen配置了default_server参数的server块。

server {
    listen 80 default_server;
    server_name _;
    return 444;
}

配置了default_server的server块,会接住所有没有匹配到任何server_name的请求,返回444是一种常见的做法,表示直接断开连接,不给任何响应,可以有效减少恶意扫描。

server_name的精准匹配顺序

nginx处理server_name时,有严格的顺序:

  • 精确匹配: server_name blog.example.com
  • 通配符前匹配: server_name .example.com
  • 通配符后匹配: server_name www.example.
  • 正则匹配: server_name ~^(www\.)?example\.com$

nginx会按这个顺序依次查找,找到第一个匹配的规则就会停止。

泛解析配置:运用通配符

有时候你需要把某个域名下的所有子域名都指向同一个网站,比如用户个人主页,此时可以用通配符虚拟主机:

server {
    listen 80;
    server_name .user.example.com;
    root /var/www/userpages/$subdomain;
}

这里有个技巧,你可以配合$host变量来动态指定目录,比如用root /var/www/userpages/$host;,这样abc.user.example.com就会自动映射到/var/www/userpages/abc.user.example.com目录下,不过需要你确保目录存在,或者用正则重写来处理。

进阶场景:基于端口和IP的虚拟主机配置

域名虚拟主机足够应对绝大多数场景,但还有两种特殊情况。

基于端口的配置:用途特定服务

比如你有一个管理后台,不想让用户通过常规80端口访问,想换个冷门端口提高隐蔽性。

server {
    listen 8080;
    server_name admin.example.com;
    root /var/www/admin;
    access_log /var/log/nginx/admin.access.log;
}

访问http://admin.example.com:8080才能打开,要注意的是,使用非80端口时,需要在云服务器安全组和防火墙里放行对应端口。

基于IP的配置:多IP服务器

如果你的服务器绑定了多个IP地址,想让不同IP访问不同的站点,只需修改listen:

server {
    listen 203.0.113.10:80;
    server_name example.com;
    root /var/www/site1;
}
server {
    listen 203.0.113.11:80;
    server_name example.com;
    root /var/www/site2;
}

这种场景现在用得少了,但在某些政企内网环境中还是会遇到。

location匹配规则:虚拟主机内部的详细路由

正确配置location,可以更精细地控制URL映射,这是nginx虚拟主机配置中提升访问精准度的关键环节,很多人只关注域名匹配,却忽视了location的优先级,导致图片加载失败或者伪静态规则失效,这一块尤其值得留意。

location匹配优先级排序

nginx的location匹配有严格优先级顺序,从上到下先匹配优先级别高的规则:

  • 精确匹配 : location = /logo.png
  • 前缀匹配 ^~: location ^~ /static/
  • 正则匹配 或 `~location ~ .php$`
  • 普通前缀匹配: location /api/

nginx会先检查精确匹配和前缀匹配,再按顺序检查正则,找到第一个匹配的规则后,如果它是^~或,就直接使用,不进行正则匹配,如果找到普通前缀匹配,则继续找正则,正则匹配到了就覆盖前缀匹配。

一个常用的静态资源配置块

比如对于常见站点,可以配置:

nginx虚拟主机配置怎么做,nginx虚拟主机配置方法有哪些

server {
    listen 80;
    server_name example.com;
    root /var/www/html;
    index index.php index.html;
    # 静态文件缓存
    location ~ \.(jpg|jpeg|png|gif|ico|css|js)$ {
        expires 30d;
        add_header Cache-Control "public, immutable";
    }
    # PHP请求转发
    location ~ \.php$ {
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
    # 拒绝访问隐藏文件
    location ~ /\. {
        deny all;
    }
}

用rewrite规则美化URL

如果想让用户访问/article/123实际转发给/index.php?id=123,可以在server块里加上:

location / {
    rewrite ^/article/(\d+)$ /index.php?id=$1 last;
}

last标记表示停止当前规则的匹配,重新发起一轮location匹配。

常见故障:配置不生效与404排查思路

新配置完虚拟主机,最容易在处理关于‘配置未生效’的问题时踩坑,我用经验帮你快速定位,直接给出可验证的排查路径。

排查业务流程

  • 运行nginx -t检查语法: 语法错误是最低级的错误,但经常发生,检查缺少分号、大括号不配对、变量名拼写错误。
  • 查看错误日志: 日志文件在/var/log/nginx/error.log,大多数格式问题、路径问题在日志里一目了然,通常带有具体的行号提示。
  • 确认是否使用了正确配置文件: 检查主配置文件的include路径是否覆盖了你编辑的文件,有的朋友编辑了sites-available下的文件,却忘了创建软链接到sites-enabled,导致配置载入失败,尤其以Debian/Ubuntu系统居多。
  • 检查文件权限: nginx运行用户通常是nginx或www-data,需要保证该用户对网站目录有读权限,否则页面结果是403,而非404。

处理404问题

404通常是root路径设置错误或location匹配不当,先看root路径下是否真的存在对应文件,如果在location中使用了alias,也要检查alias路径拼接是否正确,它是替换而不是拼接。

安全加固与性能建议

虚拟主机配置的最终目的是稳定、安全地对外提供服务,作为线上生产环境,有几个配置细节值得关注。

隐藏版本号降低被针对性攻击风险

在http块中添加:

server_tokens off;

这样nginx报错页面就不会显示版本号,能避开针对特定版本漏洞的扫描。

启用gzip压缩流量

大部分场景下,文本类内容启用gzip能显著降低带宽消耗:

gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

设置超时与连接限制

对虚拟主机做基本的资源隔离,避免单个站点耗尽连接:

server {
    listen 80;
    server_name example.com;
    client_max_body_size 10m;
    keepalive_timeout 65;
}

client_max_body_size可根据业务上传需求调整大小,这是防止大文件上传拖垮服务器的常用手段。

常见nginx虚拟主机相关疑问与解答

nginx的虚拟主机配置和Apache的虚拟主机配置差别在哪里?

两者核心逻辑都是配置基于域名或IP的多个站点,但存在三点明显差异。nginx没有独立的<VirtualHost>标签,统一用server块实现,配置语法更简洁紧凑,nginx的.htaccess机制不完全等同于Apache,通常在server块或location块中直接写规则,建议关闭Apache风格的分布式配置,以降低性能开销,nginx的高并发能力和低内存占用,让它在同等硬件条件下能支撑更多虚拟主机。

虚拟主机配置中server_name可以同时匹配多个域名吗?

可以。server_name支持一个块内并列多个域名,用空格分隔即可。 这是很常见的做法,比如使用server_name example.com www.example.com;就能实现访问主域和www子域都指向相同站点内容,这种方式适用于需要配置大量域名的虚拟主机,建议配合通配符和正则规则使用,总体匹配效率更高,运维目标也更明确,结合泛解析和default_server机制,可以构建覆盖不同需求的虚拟主机体系。

nginx修改了虚拟主机配置后为什么清理浏览器缓存才能生效?

这不是nginx本身的问题,是浏览器层级的响应机制和你的客户端本地缓存。nginx在reload之后,新生效规则已经不会影响已经建立的TCP连接和缓存响应。 而浏览器可能对静态资源启用了强缓存,本地保存了过期响应头,导致页面看起来还是旧状态,通常等待缓存自然过期即可,也可以用Ctrl+F5强制刷新,问题就会消失,属于正常现象,清理的是客户端缓存,不是服务器缓存。

结尾收束与建议

nginx虚拟主机配置的核心就是server块、server_name、root和location之间的协同工作,只要掌握了匹配优先级,并且熟悉nginx -t和nginx -s reload这套安全操作流程,你就能轻松管理一台服务器上的多个站点,千万不要图省事把所有站点都塞进一个server块里,给每个虚拟主机独立配置文件,才是长期维护的上策。

相关文章

2024年,SaaS软件行业碰到获客难、增长慢等问题吗?

我们努力让每一次邂逅总能超越期待