05-发布版:Nginx 多站点与反向代理

05-发布版:Nginx 多站点与反向代理

发布版说明

  • 已对真实域名、公网 IP、具体云厂商指代做脱敏处理。
  • 原始学习笔记未改动,这一版用于公开发布。

专题:Nginx 多站点与反向代理

这篇是把前面几次实战里反复碰到的 Nginx,单独拎出来讲透。

目标不是背配置,而是搞明白:

  1. 一个请求到了服务器以后,Nginx 到底怎么决定交给谁
  2. 为什么同一台机器可以挂很多站点
  3. 什么场景该反代到容器,什么场景直接给静态文件
  4. 为什么明明容器活着,浏览器却还是打不开

一、先把整体图看明白

前面我们已经实际搭过这几种情况:

  • status.example.com -> Uptime Kuma
  • files.example.com -> FileBrowser
  • blog.example.com -> WordPress

它们表面上是三个网站,底层其实可以共用一台服务器、一个 Nginx:

浏览器
  ->
域名
  ->
公网 IP
  ->
Nginx 80/443
  ->
根据 Host 头匹配不同站点
  ->
转发给不同应用

关键点就一句:

不是靠端口区分站点,而是靠域名区分站点。

也就是请求里这个 Host

  • status.example.com
  • files.example.com
  • blog.example.com

Nginx 看见不同的 Host,就把请求送进不同的 server 块。


二、server 块到底是什么

可以把一个 server 块理解成:

“某个域名对应的一份站点接待规则”

最基本长这样:

server {
    listen 80;
    server_name status.example.com;

    location / {
        proxy_pass http://127.0.0.1:3001;
    }
}

这里面最关键的 3 个点:

2.1 listen

表示这个站点监听哪个端口。

常见是:

  • listen 80; 表示 HTTP
  • listen 443 ssl; 表示 HTTPS

注意:

同一台机器可以有很多 server 都写 listen 80;

这不冲突,因为它们不是靠端口继续区分,而是靠 server_name 区分。


2.2 server_name

表示这份配置是给哪个域名用的。

比如:

server_name status.example.com;

它的意思不是“DNS 在这里配置”,而是:

当请求到达 Nginx,并且 Host 头等于这个域名时,这个站点配置来处理。

所以 DNS 和 Nginx 是两层事:

  • DNS 负责把域名解析到服务器 IP
  • Nginx 负责接到请求后按域名分流

2.3 location

表示:

路径怎么处理

最常见的就是:

location / {
    proxy_pass http://127.0.0.1:3001;
}

意思是:

  • 只要访问这个站点的任意路径
  • 都转发给后端应用

以后你还会遇到:

  • location /api/
  • location /static/
  • location /.well-known/acme-challenge/

这就是“同一个站点里,不同路径不同处理规则”。


三、Nginx 怎么判断一个请求该进哪个站点

这一步必须彻底搞懂,不然后面会一直被默认页、串站、证书失败折磨。

3.1 请求到达 Nginx 时,先按端口分一层

比如:

  • 请求到 80
  • 或请求到 443

Nginx 先找所有监听这个端口的 server

3.2 再按 Host 头匹配 server_name

比如浏览器请求:

http://status.example.com/

它会带上:

Host: status.example.com

于是 Nginx 去找:

  • 哪个 server 同时监听了 80
  • server_name 匹配 status.example.com

找到了,就交给它。


3.3 如果没匹配上,会掉进“默认站点”

这就是我们前面碰到的经典坑:

明明域名已经解析到服务器了,结果访问出来是:

  • Ubuntu 默认 Nginx 欢迎页
  • 或别的站点页面

原因通常不是应用挂了,而是:

这个请求没有被你想要的 server 块接住。

常见原因:

  1. server_name 写错了
  2. 配置文件没启用
  3. 改完没 reload
  4. 默认站点还在抢请求

这也是为什么这个命令特别重要:

curl -I -H "Host: status.example.com" "http://127.0.0.1"

它测的是:

  • 不走公网
  • 不依赖 DNS
  • 直接测试 Nginx 能不能按 Host 匹配到正确站点

如果这一步都不对,就不要去怀疑容器和证书,先把 Nginx 匹配修好。


四、反向代理到底在干什么

反向代理不是一个玄学词,本质上就是:

浏览器访问的是 Nginx,但 Nginx 再代你去访问真正的应用。

以前面 Uptime Kuma 为例:

浏览器
  -> http://status.example.com
  -> Nginx
  -> http://127.0.0.1:3001
  -> Uptime Kuma

这时候浏览器根本不知道 3001 的存在。

它只知道自己在访问:

status.example.com

这样做的好处很大:

  1. 应用可以只绑定本机端口,不直接暴露公网
  2. HTTPS 统一由 Nginx 处理
  3. 多个应用可以共用 80/443
  4. 将来换后端端口,前端域名不变

这就是为什么我们前面一直坚持:

ports:
  - "127.0.0.1:3001:3001"

而不是直接把应用暴露成公网 3001


五、静态站点和反代站点有什么区别

这两个概念很容易混。

5.1 静态站点

比如一个纯 HTML 页面:

server {
    listen 80;
    server_name demo.example.com;

    root /var/www/demo;
    index index.html;
}

这里 Nginx 自己就能把文件读出来返回给浏览器。

这叫:

Nginx 直接提供静态文件。


5.2 反代站点

比如 FileBrowser

server {
    listen 80;
    server_name files.example.com;

    location / {
        proxy_pass http://127.0.0.1:8081;
    }
}

这里真正返回页面的不是 Nginx,而是后面的应用。

Nginx 只是中转。

所以:

  • 返回 404,不一定是 Nginx 的 404,也可能是后端应用自己的 404
  • 返回 302,也可能是后端应用自己的跳转

这就是前面你碰到 curl -I http://127.0.0.1:8081 返回 404,但直接拉 / 却能看到 HTML 的原因:

你测到的是应用自己的响应,不是 Nginx 配错了。


六、为什么同一台机器能挂很多应用

因为站点入口统一由 Nginx 承担,而后端应用都只监听本机不同端口。

比如:

status.example.com -> 127.0.0.1:3001
files.example.com  -> 127.0.0.1:8081
blog.example.com   -> 127.0.0.1:8082

这时候对外看:

  • 都是 80/443

对内看:

  • 每个应用各守自己的本机端口

这就是部署多站点最常见的骨架。


七、你前面实战里真正踩到的几个关键坑

7.1 域名能解析,不代表站点一定对

比如:

dig +short "status.example.com"

返回了服务器 IP,只能证明:

  • DNS 这一层通了

不能证明:

  • Nginx 站点配置正确
  • 容器活着
  • HTTPS 正常

7.2 本机反代通,不代表公网一定通

前面最典型的问题就是:

  • 本机 curl 已经能访问
  • 证书、本地 443、Nginx 也都正常
  • 但外网访问 HTTPS 超时

最后发现不是 Nginx,而是:

云厂商安全组没放行 443

这件事非常重要,因为它说明网络是分层的:

  1. 应用层
  2. Nginx 层
  3. Linux 防火墙层
  4. 云厂商安全组层

任何一层拦住,外面都访问不到。


7.3 curl -I 和浏览器看到的不是一回事

比如:

curl -I "http://status.example.com"

你看到的是:

302 Found
Location: /dashboard

这其实是正常的。

因为很多应用首页本来就会跳转。

所以看到 302 不要第一反应就觉得坏了,继续测:

curl -I "http://status.example.com/dashboard"

如果这里是 200,那反而说明链路已经基本通了。


7.4 ACME 挑战路径被站点规则吞了

前面证书申请失败时,错误信息里最核心的一句是:

访问 /.well-known/acme-challenge/... 时,拿到的不是挑战文件,而是你站点自己的 HTML。

这说明:

  • Certbot 把挑战文件写到了某个 webroot
  • 但 Nginx 没有优先把这个路径映射到挑战目录
  • 请求被其他 location / 或静态页规则接走了

这也是为什么申请证书时,HTTP 站点不能只想着“首页能打开就行”。

还要保证:

/.well-known/acme-challenge/

这条路径返回的是 challenge 文件本身。


八、以后判断一个站点问题,按什么顺序查

这是现在最应该固定下来的排障顺序。

第 1 步:先查 DNS

dig +short "status.example.com"

看域名是不是已经指向你的服务器 IP。


第 2 步:查本机应用是不是活着

比如:

curl -I "http://127.0.0.1:3001"
curl -I "http://127.0.0.1:8081"
curl -I "http://127.0.0.1:8082"

如果这一步不通,先别看 Nginx。


第 3 步:查 Nginx 是否能按域名接住请求

curl -I -H "Host: status.example.com" "http://127.0.0.1"

如果这里不对,问题多半在:

  • server_name
  • 站点没启用
  • 默认站点
  • 没 reload

第 4 步:查 Nginx 配置有没有语法错

sudo nginx -t
sudo systemctl reload nginx

别改完配置不验证,那个最容易把自己绕晕。


第 5 步:查端口监听

sudo ss -lntp | grep -E ':80|:443|:3001|:8081|:8082'

看看到底是谁在监听:

  • Nginx 是否监听了 80/443
  • 应用是否监听了它自己的本机端口

第 6 步:查公网链路

如果本机都正常,但公网不通,就查:

  • ufw
  • 云厂商安全组

必要时可以这样测本机 HTTPS:

curl -vkI --resolve "status.example.com:443:127.0.0.1" "https://status.example.com"

这个命令的意义是:

  • 强行把域名解析到本机 127.0.0.1
  • 直接测试“本机上的 HTTPS 站点”本身有没有问题

如果这一步通,但公网还是超时,那就基本不是 Nginx 配置问题了。


九、一个最小可用的多站点脑图

现在可以把你的服务器理解成这样:

203.0.113.10
  ->
Nginx 80/443
  ->
按域名分流
  ->
status.example.com -> 127.0.0.1:3001 -> Uptime Kuma
files.example.com  -> 127.0.0.1:8081 -> FileBrowser
blog.example.com   -> 127.0.0.1:8082 -> WordPress

只要这个结构脑子里清楚了,以后你再上:

  • MinIO
  • Nextcloud
  • Gitea
  • Vaultwarden
  • Plausible

本质都还是同一个套路。

变化只在:

  1. 后端应用监听哪个端口
  2. 它是否需要数据库
  3. 它的站点路径和头部是否有特殊要求

十、这一课学完后,你应该真正掌握的东西

不是会背某份配置,而是知道:

  1. server 块是在按域名接请求
  2. server_name 不对,站点就接不住
  3. 默认页出现,大概率不是应用挂了,而是站点匹配错了
  4. proxy_pass 是把请求转发给后端应用
  5. 同一台机器挂多个站点,核心不是多开公网端口,而是域名分流
  6. 本机通、公网不通,要想到安全组和防火墙
  7. 证书申请失败,常常不是证书本身有问题,而是挑战路径没被正确接住

十一、下一步最适合继续学什么

下一课建议接:

HTTPS 与 Let’s Encrypt

因为现在你已经知道:

  • Nginx 怎么按域名接请求
  • 反代怎么把流量送给后端

下一步就该把这件事彻底吃透:

  1. 证书申请到底依赖什么条件
  2. HTTP-01 挑战到底在验证什么
  3. 为什么“本机能开网页”不等于“证书一定能签下来”
  4. 证书签发、续期、443 放行之间到底是什么关系

这一课接上去,会非常顺。

© 版权声明
THE END
喜欢就支持一下吧
点赞5 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容