用在ubuntu上给nginx绑定多个域名,核心做法就是为每个域名单独写一个server块,或者让多个域名共用同一套配置再按项目拆开管理,没有比这更简洁可靠的方案了。搞清楚server块的匹配规则,多域名部署就是套模板的事。
ubuntu nginx配置多个域名,先搞清server块
很多人第一次接触nginx多域名时,习惯去改http块里的全局配置,结果所有域名都指向同一个页面,原因在于nginx的配置逻辑是按server块区分站点,而不是按域名自动识别目录。
一个server块就是一台“虚拟主机”,nginx收到请求后,会根据请求头里的Host字段去匹配server_name,匹配上了就交给对应的server块处理,所以在ubuntu上绑定多个域名,本质就是写多个server块,每个块声明自己的server_name和root目录。
以ubuntu 22.04 LTS为例,nginx的站点配置一般放在以下路径:
/etc/nginx/sites-available/:存放站点配置文件的目录,相当于“可用站点池”/etc/nginx/sites-enabled/:存放启用配置的目录,默认通过软链接指向sites-available/etc/nginx/nginx.conf:主配置,末尾会include sites-enabled下的所有文件
行业共识是,不要把server块直接写进nginx.conf,而是每个域名单独建一个文件,放到sites-available里,再做个软链接到sites-enabled,这样维护起来清清楚楚,禁用一个站点只需删掉软链接,不用动其他配置。
实战:两个域名绑定同一台ubuntu服务器的完整过程
假设你有一台ubuntu服务器,IP是0.113.10,手上有两个域名:
www.example-a.com,网站目录放/var/www/site-awww.example-b.com,网站目录放/var/www/site-b
先在服务器上建好两个网站目录,并放入测试页面:
sudo mkdir -p /var/www/site-a /var/www/site-b echo '<h1>Site A</h1>' | sudo tee /var/www/site-a/index.html echo '<h1>Site B</h1>' | sudo tee /var/www/site-b/index.html
接着在sites-available下创建两个配置文件:
sudo nano /etc/nginx/sites-available/site-a.conf
写入:
server {
listen 80;
listen [::]:80;
server_name www.example-a.com example-a.com;
root /var/www/site-a;
index index.html index.htm;
access_log /var/log/nginx/site-a-access.log;
error_log /var/log/nginx/site-a-error.log;
}
同样的方式创建site-b.conf,改掉server_name和root路径,然后启用这两个站点:
sudo ln -s /etc/nginx/sites-available/site-a.conf /etc/nginx/sites-enabled/ sudo ln -s /etc/nginx/sites-available/site-b.conf /etc/nginx/sites-enabled/
删除nginx自带的default站点,避免它抢占默认server位置:
sudo rm -f /etc/nginx/sites-enabled/default
检查配置语法并重载:
sudo nginx -t sudo systemctl reload nginx
这时候在浏览器分别访问两个域名,就能看到各自的页面。核心就三步:建目录、写server块、启用配置,整个过程不需要重启服务器,reload就够。
如果两个域名指向同一个网站怎么办
这种情况更简单,让两个域名共用同一个root即可,用方括号列出多个server_name:
server {
listen 80;
server_name example-a.com www.example-a.com example-b.com www.example-b.com;
root /var/www/site-a;
# 其他配置
}
访问任何一个域名都会命中这个server块,如果你想保留一个主域名做301跳转,把所有流量归到主域名上,再单独加一个server块:
server {
listen 80;
server_name example-b.com www.example-b.com;
return 301 http://www.example-a.com$request_uri;
}
这样用户访问b域名,浏览器地址栏会直接跳转到a域名,URL参数原样保留,业内专家指出,多域名GEO场景下统一主域名有助于权重集中,建议用301而不是302。
nginx多个域名怎么分开?按项目拆分配置文件
当你的网站数量超过3个,继续往sites-available里堆文件虽然可行,但找起来麻烦,更规范的做法是按项目拆分配置,把每个域名的server块拆成两个文件:一个只管HTTP,一个只管HTTPS,或者直接把配置按业务域拆成独立文件。
另一种常见思路是把公用的配置抽离成片段,比如所有站点都要用的gzip、缓存策略,写成/etc/nginx/conf.d/common.conf,然后每个server块里用include引入,这样多个域名共用基础配置,实际修改时只需要动业务相关的部分。
具体结构参考:
/etc/nginx/ ├── sites-available/ │ ├── site-a.conf │ ├── site-b.conf │ └── site-c.conf └── conf.d/ ├── common.conf └── cache.conf
这种做法的优势在于:单个域名出现问题,排查范围被限制在一个文件里,不会牵连其他站点,对于一台服务器上跑五六个域名的场景,这是最省心的组织方式。
ubuntu nginx一个端口绑定多个域名,server_name规则详解
80端口只有一个,但nginx可以承载无数个域名,靠的就是server_name匹配,理解匹配规则的优先级,能帮你避开很多“为什么域名指向了错误的站点”这类问题。
nginx在收到请求时,按以下顺序寻找匹配的server块:
| 优先级 | server_name写法 | 示例 |
|---|---|---|
| 1 | 精确匹配 | server_name www.example-a.com; |
| 2 | 通配符前缀 | server_name .example-a.com; |
| 3 | 通配符后缀 | server_name www.example-; |
| 4 | 正则表达式 | server_name ~^wwwd+.example.net$; |
| 5 | 默认server | listen 80 default_server; |
也就是说,如果两个server块的server_name都能匹配同一个域名,nginx会优先选精确匹配的那个,如果所有server块都匹配不上,就落到default_server,没有声明的话,nginx默认选择加载顺序排第一个的server块,这就是为什么你明明配置了正确的server_name,请求却总跑错地方很可能是default站点没删干净。
多个域名配置SSL证书怎么处理
当今的网站基本都要上HTTPS,多域名绑定跑不了要配SSL,有两种主流方案:
- 每个域名独立SSL证书:为每个server块单独配置
ssl_certificate和ssl_certificate_key,适用于用Let’s Encrypt免费证书、或者各有独立付费证书的场景。 - SAN证书一个顶多个:一张证书里同时包含多个域名,比如
.example-a.com加example-a.com,所有域名共用一个证书文件,配置更简洁,适合同主域下的多个子域名。
以Let’s Encrypt的certbot为例,一条命令就能给多个域名签证书:
sudo certbot --nginx -d example-a.com -d www.example-a.com -d example-b.com
certbot会自动修改nginx配置文件,把80端口跳转和443监听一并配置好,装完证书后重载nginx:
sudo systemctl reload nginx
用certbot配置的多域名SSL证书,后续续期也是全自动的,不需要手动干预。
多域名绑定后的验证方法和常见坑
配置写完了,如何确认所有域名都生效?分四步验证:
- 用
sudo nginx -t验证配置语法,这一步能过滤掉90%的书写错误。 - 用
curl -H "Host: www.example-a.com" http://127.0.0.1在服务器本机测试,不走DNS,直接验证nginx的匹配结果。 - 检查监听端口,
sudo netstat -tlnp | grep nginx确认80和443端口都在监听。 - 看访问日志,
tail -f /var/log/nginx/access.log,访问一次域名看日志输出。
常见的问题集中在几个地方:
- 配置文件里少了分号,nginx -t会直接报错,按提示行号逐行排查。
- 防火墙没放行443端口,
sudo ufw allow 443/tcp提前做好。 - sites-enabled里的软链接路径写错,导致配置没被加载,用
ls -l /etc/nginx/sites-enabled/检查。 - 域名解析没生效,在本地用
dig www.example-a.com确认A记录指向服务器IP。
据统计,绝大多数“nginx多个域名配置无效”的案例,最后查出来都是DNS解析或者default_server拦截的问题,不是nginx配置本身写错。
配置多个域名的本质很简单:nginx只管按Host字段路由,域名指向哪里由DNS决定,把这两件事分开想,排查思路就清晰了。
常见问题解答
ubuntu nginx绑定多个域名时,一个域名能配置多个端口吗
能,在同一个域名对应的server块里,可以分别监听80和443端口:
server {
listen 80;
listen 443 ssl;
server_name www.example-a.com;
# 证书配置...
}
访问80端口时自动走HTTP,访问443时走HTTPS,两者共用同一个server_name,你也可以分开写两个server块,但放在一起更省事,还能利用一个块内的统一rewrite规则。
nginx多个域名绑定同一个IP,访问时怎么区分
靠HTTP请求头里的Host字段区分,浏览器发起请求时,会带上用户输入的域名作为Host头,nginx解析这个字段后去server_name索引里查找匹配项,把请求路由到对应的server块,如果两个域名的A记录指向同一个服务器IP,nginx依然能正确区分,这就是虚拟主机机制的核心,如果Host完全匹配不上任何server_name,nginx会把请求交给default_server处理。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/630725.html





