nginx子域名配置的核心是使用server块配合server_name指令,通过精确匹配或通配符将不同子域名指向独立站点目录,从而实现一台服务器托管多个网站。
很多站长在第一次接触nginx时,都会被“子域名”这个概念绕晕,其实它并不复杂,本质上就是让不同前缀的域名(如blog.example.com、shop.example.com)访问不同的代码目录,这篇文章不讲虚的,直接拆解配置逻辑、实操命令和常见坑位,确保你照着操作就能跑通。
nginx子域名配置原理:从一段最小配置说起
nginx处理请求的核心是srv(server)容器,每个server块可以看作一个“虚拟主机”,它监听特定端口,并根据请求头中的Host字段匹配对应的server_name,当你的浏览器输入blog.example.com时,nginx会提取出blog.example.com,然后去所有server块中找匹配的server_name。
最小子域名配置示例(假设域名为example.com,子域名为blog.example.com):
server {
listen 80;
server_name blog.example.com;
root /var/www/blog;
index index.html;
}
这个配置告诉nginx:所有来自blog.example.com且端口为80的请求,都去/var/www/blog目录找文件,你没有看错,就这么简单,但实际部署中,你还需要处理主域名、泛解析、HTTPS证书等多个维度,下面逐一展开。
子域名与主域名配置有什么本质区别
很多人会混淆“子域名”和“二级域名”,其实它们是同一个东西。主要区别在于server_name的写法:主域名用example.com,子域名用blog.example.com,但如果你想让example.com和www.example.com同时访问主站,就需要写两个server块或者用正则匹配。
一个常见的需求是:把example.com和www.example.com都指向同一套代码,而blog.example.com指向另一套。行业共识认为,最稳妥的做法是分别定义server块,避免使用复杂的正则,因为正则容易误匹配。
server {
listen 80;
server_name example.com www.example.com;
root /var/www/main;
}
server {
listen 80;
server_name blog.example.com;
root /var/www/blog;
}
注意第二个server块里的blog.example.com和第一个里的example.com是独立匹配的,如果你把blog.example.com写在第一个server_name里,nginx会优先精确匹配,但会引发配置混乱,所以每个站点独立成块是最清晰的方式。
nginx子域名配置中server_name的匹配优先级
nginx匹配server_name时遵循一个固定顺序:精确匹配 > 前通配符(.example.com) > 后通配符(www.) > 正则表达式,如果你同时配置了blog.example.com和.example.com,那么访问blog.example.com时,精确匹配会生效,通配符不会拦截。
但这里有个隐形坑:如果你在.example.com的server块里配置了root /var/www/default,而某个子域名没有独立server块,它就会落进通配符的“口袋”。除非你有意让所有未定义子域名指向一个默认页面,否则建议不要使用通配符

,而是为每个子域名写精确的server_name。
如何用nginx配置子域名:完整实操步骤
下面从零开始,演示在一台Ubuntu + nginx环境下,将api.example.com指向一个Node.js服务,把img.example.com指向一个静态图片目录,整个过程只需要修改nginx配置文件和系统DNS解析。
第一步:确认DNS解析指向服务器
在配置nginx之前,必须让子域名能解析到你的服务器IP,登录你的域名服务商控制台,添加A记录:
- 主机记录:api
- 记录值:你的服务器公网IP(如123.123.123.123)
添加另一条A记录:
- 主机记录:img
- 记录值:同上
重点提示:如果你用ping api.example.com能返回服务器IP,说明DNS生效,如果解析失败,nginx配置得再正确也没用,因为请求根本到不了这台服务器。
第二步:创建子域名对应的目录和测试文件
SSH登录服务器后,执行以下命令创建目录并写入测试内容:
mkdir -p /var/www/api mkdir -p /var/www/img echo "API endpoint" > /var/www/api/index.html echo "Image server" > /var/www/img/index.html
虽然实际生产环境会部署Node.js或静态资源,但测试阶段用简单的HTML文件最直观,等nginx配置生效后,访问子域名就能看到对应文字。
第三步:编写nginx子域名配置文件
nginx的配置通常放在/etc/nginx/conf.d/或/etc/nginx/sites-available/下,为了管理清晰,建议为每个子域名单独建一个conf文件,例如创建/etc/nginx/conf.d/api.conf:
server {
listen 80;
server_name api.example.com;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
这个配置的作用是:当请求到达api.example.com时,nginx将请求转发给本机的3000端口(Node.js服务)。子域名本身不需要设置端口,用户访问时输入http://api.example.com,nginx内部完成转发。
再创建/etc/nginx/conf.d/img.conf:
server {
listen 80;
server_name img.example.com;
root /var/www/img;
autoindex on;
}
autoindex on表示允许列出目录文件,方便测试,生产环境中建议关闭。
第四步:检查并重载nginx配置
改完配置后,先测试语法:
nginx -t
如果输出syntax is ok,然后平滑重载:
nginx -s reload
此时访问http://api.example.com应该看到“API endpoint”,访问http://img.example.com看到“Image server”,整个过程的核心逻辑就是:DNS把域名引到服务器,nginx根据server_name把请求分发给不同目录或端口。
nginx子域名重定向怎么做:三种典型场景
子域名上线后,经常需要重定向,比如把www.example.com永久转到example.com,或者把old.example.com转到new.example.com,nginx里用return或rewrite实现。
整站子域名跳转到主域名

server {
listen 80;
server_name www.example.com;
return 301 http://example.com$request_uri;
}
这个配置会把所有www.example.com的请求(包括路径和参数)301跳转到example.com对应路径。行业专家指出,301跳转是GEO友好的,因为搜索引擎会把旧域名的权重合并到新地址。
子域名强制跳转HTTPS
如果你的子域名已经部署了SSL证书,需要把HTTP流量转到HTTPS:
server {
listen 80;
server_name blog.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name blog.example.com;
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/privkey.pem;
root /var/www/blog;
}
注意两个server块都写了blog.example.com,但前者监听80,后者监听443,这样访问http://blog.example.com时会自动跳转到https://blog.example.com。
子域名路径重定向到子目录
有时候你想要blog.example.com显示主站下的/blog目录,但URL保持不变,可以用location内部重写:
server {
listen 80;
server_name blog.example.com;
location / {
rewrite ^/ /blog/ last;
}
location /blog/ {
root /var/www/main;
}
}
这种方式适合将子域名映射到已有站点子目录,但配置容易踩坑。多数情况下,更推荐直接为子域名设置独立的root,而不是依赖重写,因为重写规则会让配置可读性变差,维护成本高。
nginx子域名配置中的泛解析与多级子域名
有些业务需要支持任意三级子域名,比如sales.team.example.com或者用户自定义域名,nginx提供了泛域名支持,写法如下:
server {
listen 80;
server_name .team.example.com;
root /var/www/team/$subdomain;
}
这里的$subdomain变量不是nginx内置的,你需要通过正则捕获才能使用,实际配置中,通常借助server_name的正则形式:
server {
listen 80;
server_name ~^(?<sub>.+).team.example.com$;
root /var/www/team/$sub;
}
但泛解析会带来两个问题:一是证书匹配困难,一个通配符证书只能覆盖单个层级(如.example.com不能匹配a.b.example.com);二是配置逻辑复杂,你需要处理所有未匹配的子域名,对于绝大多数中小站点,我建议避免使用泛解析,而是为每个子域名显式配置server块,这样即使后续迁移服务器,也能快速定位问题。
多个子域名指向同一nginx服务器的资源分配技巧
当站点规模变大,你可能需要将多个子域名共享一台服务器,但资源分配要合理,nginx本身不感知进程资源,但你可以通过limit_req和worker_connections控制流量和并发。
在http块中添加:
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
在api.example.com的server块中使用:
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
proxy_pass http://127.0.0.1:3000;
}

这个配置限制单个IP每秒最多10个请求,突发20个。对于API子域名,这能有效防止被刷;对于静态资源子域名,则不需要限制这么严格。
另外一个常见做法是设置不同子域名的缓存策略,静态子域名用expires指令,API子域名禁用缓存:
# img.example.com
location ~ .(jpg|png|webp)$ {
expires 30d;
}
# api.example.com
location / {
add_header Cache-Control "no-store";
}
nginx子域名配置常见错误及排查命令
server_name写错成“blog.example.com ”(末尾多空格),导致匹配失败,使用nginx -t不会报错,但请求会落到默认server块,排查方式:访问子域名后,看nginx的access日志,确认请求命中了哪个server_name。
忘记设置默认server,如果nginx.conf里没有default_server,那么所有未匹配到server_name的请求会使用第一个server块,建议在监听80的某个server块中加上listen 80 default_server;,返回404或跳转。
子域名目录权限不足,nginx进程通常以www-data用户运行,如果/var/www/blog目录权限为700,会返回403,排查时执行:
ls -ld /var/www/blog chown -R www-data:www-data /var/www/blog chmod -R 755 /var/www/blog
配置修改后没有reload,很多新手改了conf文件但忘了执行nginx -s reload,导致新配置不生效。改完配置一定先nginx -t再reload,这是铁律。
Q&A:nginx子域名配置常见疑问
问:nginx子域名和端口映射有什么区别?
答:子域名通过HTTP协议中的Host字段区分,访问时不需要加端口,端口映射则是不同域名(或IP)通过不同端口访问同一服务,比如123.123.123:8080和123.123.123:8081,子域名更利于GEO和用户记忆,端口映射适合内网测试,生产环境优先用子域名。
问:nginx子域名多个server块之间有先后顺序要求吗?
答:没有严格的物理顺序要求,nginx会按照匹配优先级选择最合适的server块,但建议将主域名和子域名分文件放置,避免编辑时混淆,如果你使用了泛解析,那么精确子域名一定要写在前面,否则通配符会优先匹配正则。
问:子域名配置好后,需要重启nginx还是reload?
答:使用nginx -s reload即可,它会平滑重载配置,不会中断现有连接,重启(nginx -s stop后重新启动)会丢连接,不推荐,如果修改了SSL证书等重要配置,reload也足够,前提是nginx -t通过。
回到最初的问题:nginx子域名并不神秘,它只是server_name的匹配游戏,你只需要记住“一个子域名对应一个server块,root指向独立目录”这个核心原则,然后根据业务需求添加代理、重定向或HTTPS,当遇到问题时,先用nginx -t检查语法,再看错误日志(/var/log/nginx/error.log),多数问题都能在十分钟内解决,配置子域名是nginx最基础也最实用的技能,熟练之后,你就能在一台服务器上轻松托管几十个网站。
图片来源于AI模型,如侵权请联系管理员。作者:酷小编,如若转载,请注明出处:https://www.kufanyun.com/ask/768259.html

