微信优化

weixinyouhua

nginx配置多域名怎么实现?nginx多域名配置方法有哪些?

2026-09-26 00:01:27

nginx配置多域名并不复杂,核心在于利用server块配合server_name指令实现域名分流,一个80端口即可承载多个网站,关键在于配置顺序与默认server的处理。

nginx一个服务器配置多个域名的核心逻辑

很多朋友第一次接触nginx多域名配置时,会下意识觉得需要多个端口或多个IP,实际上nginx的虚拟主机机制早就解决了这个问题,每个server块就是一个虚拟主机,nginx收到请求后,会根据请求头中的Host字段去匹配对应的server块,匹配规则简单粗暴:先精确匹配,再通配符匹配,最后正则匹配。

举个例子,你把blog.example.com和shop.example.com都解析到同一台服务器的同一个IP上,nginx收到访问blog.example.com的请求时,看到Host是blog.example.com,就会去server块里找server_name写了这个名字的那个配置,找到就进去执行,没找到?那就走进默认server,一般是第一个加载的或显式标记default_server的那个。

这里有个常见误解要澄清:server_name本身不解析域名,也不监听端口,它只是nginx做请求路由的一个标识,DNS解析发生在请求到达nginx之前,所以你得先把所有域名的A记录都指向服务器IP,这一步是前提。

server_name匹配规则的优先级

行业共识认为,server_name的匹配优先级从高到低依次是:

  • 精确匹配,比如server_name www.example.com;
  • 前通配符,比如server_name .example.com;
  • 后通配符,比如server_name www.;
  • 正则匹配,比如server_name ~^www.d+.example.com$;

如果你的多个域名长得特别像,比如example.com和www.example.com,记得把精确匹配的写在前面,或者干脆用通配符server_name .example.com;一把梭,这个写法同时匹配裸域和www子域。

默认server的坑

很多人配置完nginx多域名后发现,访问域名A打开了域名B的站点,十有八九是默认server在捣鬼,当你用IP直接访问,或者Host头没匹配到任何server_name时,nginx会把请求交给默认server。建议单独创建一个默认server块,直接返回444状态码或跳转到你的主域名,避免别人用IP扫到你的其他站点。

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

这个return 444是nginx特有的,直接断开连接不返回任何响应,用来防扫描很顺手。

nginx配置多个域名共用80端口的实操步骤

假设你有一台服务器,要跑example.com和test.cn两个站点,两个都是纯静态页面,具体操作路径如下:

nginx配置多域名怎么实现?nginx多域名配置方法有哪些?

第一步:准备站点目录

mkdir -p /var/www/example.com
mkdir -p /var/www/test.cn

把对应网站的静态文件放进去,目录权限记得设置好,nginx进程用户一般是www-data或nginx,确保有读取权限。

第二步:创建独立的配置文件

nginx的配置有个好习惯:一个站点一个conf文件,放在/etc/nginx/conf.d/目录下,主配置nginx.conf里用include /etc/nginx/conf.d/.conf;引入,这样后续维护时删改单个站点不会影响其他。

创建/etc/nginx/conf.d/example.com.conf:

server {
    listen 80;
    server_name example.com www.example.com;
    root /var/www/example.com;
    index index.html;
    access_log /var/log/nginx/example.com.access.log;
    error_log /var/log/nginx/example.com.error.log;
}

再创建/etc/nginx/conf.d/test.cn.conf:

server {
    listen 80;
    server_name test.cn;
    root /var/www/test.cn;
    index index.html;
}

两个文件都监听80端口,但server_name不同,nginx完全可以区分。

第三步:检查语法并重载

这一步强烈建议养成肌肉记忆,每次改完配置都要跑一遍:

nginx -t
systemctl reload nginx

nginx -t用来检查语法,出错的话它会明确告诉你哪个文件哪一行有问题,大概率是缺分号或花括号没闭合。语法检查通过后再reload,千万别直接restart,reload是平滑重载不会断连接,restart会有一瞬间的服务中断。

第四步:本地验证

用curl指定Host头模拟请求,不用等DNS生效就能测:

curl -H "Host: example.com" http://127.0.0.1
curl -H "Host: test.cn" http://127.0.0.1

返回不同页面内容就说明配置生效了。

动态域名与泛解析的配置技巧

如果域名数量特别多,比如user1.example.com、user2.example.com这种用户子域名场景,一个个写server块实在不优雅,nginx支持正则匹配server_name,配合$host变量可以做到动态路由。

server {
    listen 80;
    server_name ~^(?<subdomain>.+).example.com$;
    root /var/www/$subdomain;
    index index.html;
    if (!-e $request_filename) {
        rewrite ^ /index.html last;
    }
}

这样只要目录存在,任何子域名都能直接对应到同名目录,但这招有个前提:DNS那边要用泛解析,把`

nginx配置多域名怎么实现?nginx多域名配置方法有哪些?

.example.com`的A记录也指到服务器IP上,另外正则server_name的优先级最低,跟其他精确域名混用时小心被抢走请求。

nginx多域名ssl证书怎么配置

2017年以后百度对HTTPS站点有收录倾斜,这个不用多说,多域名配HTTPS有两种路子:一个域名一个证书,或者一张多域名证书覆盖所有域名。

一个域名一个证书的写法

Let’s Encrypt的免费证书90天续期一次,配合certbot工具可以自动续期,配置示例:

server {
    listen 443 ssl;
    server_name example.com www.example.com;
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    root /var/www/example.com;
    index index.html;
}
server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://$host$request_uri;
}

这里的第二个server块负责把HTTP流量301跳到HTTPS,注意跳转时要带上$request_uri,不然用户访问的具体页面路径会丢失,跳到首页算轻的,影响收录就麻烦了。

泛域名证书

如果你管着一大堆子域名,.example.com的泛域名证书比多域名证书性价比高得多,一张证书覆盖所有子域名,写法差别只在证书文件:

ssl_certificate /etc/nginx/ssl/example.com.pem;
ssl_certificate_key /etc/nginx/ssl/example.com.key;

获得SSL证书之后配置多域名HTTPS,核心步骤其实就是改证书路径和监听443端口,逻辑跟80端口完全一致。

nginx配置域名后访问不了的排查路径

这个问题我看到过太多次了,十个里八个是防火墙或安全组没放行,按照下面顺序排查,多数情况下能快速定位。

检查端口监听状态

ss -tlnp | grep nginx

看nginx是否真的在监听80或443端口,如果输出里没有相关行,说明nginx没起来或配置有误,跑一下nginx -t看报错。

检查云服务器安全组

简米云、酷番云、华为云的服务器除了系统自带防火墙,还有一层安全组在云控制台里。安全组没放行80端口,外面无论如何都连不上,但你在服务器本机curl localhost却能通,这是最典型的症状。

检查系统防火墙

firewall-cmd --list-all    # CentOS 7+
ufw status                  # Ubuntu

CentOS默认的firewalld或者Ubuntu的ufw,手动放行端口:

firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --reload

nginx配置多域名怎么实现?nginx多域名配置方法有哪些?

检查DNS解析

dig +short example.com
nslookup example.com

看解析结果是否指向你服务器IP,如果域名是刚买的,DNS生效需要时间,国内云厂商的DNS一般几分钟到几小时。

nginx多域名配置的常见问题

多个域名指向同一个站点怎么处理

直接在server_name后面空格拼接:

server_name example.com example.net example.org;

别忘了加www开头的变体:server_name example.com www.example.com;。

主域名和子域名想用不同站点

主域名一个server块,子域名另一个server块,各自指向独立目录,这就是标准的nginx配置多域名虚拟主机思路。

域名后面带端口号访问

http://example.com:8080这种,需要在listen指令里指定端口:

server {
    listen 8080;
    server_name example.com;
}

或者用listen 80;支持默认端口访问,域名后面不用带端口,生产环境还是建议走80/443,8080这类端口容易被扫描器盯上。

多域名配置文件和apache的.htaccess有什么区别

nginx没有目录级配置文件,所有规则都集中在server块里,改完必须reload才生效,换nginx之后,原来apache的RewriteRule要改写成nginx的rewrite语法,伪静态规则迁移是最容易踩坑的点。

nginx多域名配置答疑

问:nginx配置多域名一定要买多域名SSL证书吗?
不一定,两个域名可以分别申请免费证书,各自配置独立的证书文件路径,一张多域名证书在证书管理上稍微省事,但续期、部署的复杂度跟多张证书差别不大,如果域名超过五个,用泛域名证书或通配符证书更划算。

问:nginx多域名配置教程里说改完配置要restart,但restart后服务真的会断吗?
会,restart会先停掉nginx进程再启动,这个过程中所有正在处理的请求都会断开,reload则是平滑重载,master进程重新加载配置,worker进程逐个替换,不影响正在进行的请求,所以线上环境改配置一律用reload,只有在nginx二进制升级或配置文件完全混乱时才考虑restart。

问:多个域名共用一个配置文件,还是分开写更好?
分开写,一个域名一个文件,文件名跟域名对应,比如example.com.conf,后面要找配置的时候一眼就能定位,所有域名挤在一个文件里,改一个站点的规则时容易手滑碰到别的配置,而且nginx读取配置文件是按顺序加载的,后面万一有语法错误,可能牵连整个文件里的站点全部挂掉。

相关文章

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

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