Nginx 反向代理入门:让一台服务器跑多个网站

举报
yd_254412059 发表于 2026/10/25 07:21:20 2026/10/25
【摘要】 一台服务器如何跑多个网站?本文用可直接落地的步骤讲清 Nginx 反向代理:安装启动、server 块与 proxy_pass、proxy_set_header 的作用、按域名分流多站点,以及改完先 nginx -t 再 reload,最后给出 502 的排查清单。

一台云服务器只有一个公网 IP、80 和 443 端口却要跑多个网站时,最直接的办法不是给每个网站各开一个端口,而是让 Nginx 站在前面做反向代理:浏览器先访问 Nginx,Nginx 再按域名把请求转发给本机不同端口、甚至不同目录的后端。这样对外只暴露 80/443,后端可以随便换端口、重启、扩容,用户感知不到。

一、安装并确认 Nginx 能跑起来

以 Ubuntu/Debian 为例:

sudo apt update
sudo apt install -y nginx
sudo systemctl enable --now nginx
nginx -v
sudo systemctl status nginx

安装完成后先在浏览器访问服务器 IP,能看到 Nginx 欢迎页说明服务已起。如果访问不通,先看两层放行:云服务器安全组放行 80/TCP(用 HTTPS 再放行 443/TCP),服务器本机防火墙也要放行,例如 sudo ufw allow 'Nginx Full'。不要一上来就改配置,先确认默认页能打开。

二、先理解 server 块:域名是分流的钥匙

Nginx 靠 server_name 区分网站。一个最简单的静态站点 server 块长这样:

server {
    listen 80;
    server_name www.example.com;
    root /var/www/example;
    index index.html;
    location / {
        try_files $uri $uri/ =404;
    }
}

listen 是监听端口,server_name 是域名,root 是网站文件目录,location / 决定这个路径怎么处理。反向代理就是把 location 里的 root 换成 proxy_pass:不再读本地文件,而是把请求转给后端。

三、一个能用的反向代理配置

假设本机跑了两个后端:博客在 3000 端口,API 在 8000 端口。把配置写进 /etc/nginx/conf.d/sites.conf(或 sites-available 后做软链接到 sites-enabled,两种方式选一种,不要两处重复写同一个域名):

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

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

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

    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

这几行 proxy_set_header 很重要,不能省。Host 让后端知道用户访问的是哪个域名;X-Real-IP 和 X-Forwarded-For 让后端日志和限流看到真实访客 IP,而不是永远的 127.0.0.1;X-Forwarded-Proto 让后端知道原始请求是 http 还是 https,避免生成错误的跳转链接。

注意 proxy_pass 末尾斜杠的区别:proxy_pass http://127.0.0.1:3000; 会把完整路径原样转发;proxy_pass http://127.0.0.1:3000/; 则会把 location 匹配到的前缀替换掉。只在明确需要改路径时才加斜杠,平时先用不带斜杠的写法。

四、多站点按域名分流:关键在 DNS 和 server_name

  1. 把 blog.example.com 和 api.example.com 的 DNS A 记录都指向同一台服务器的公网 IP。
  2. Nginx 里分别为每个域名写一个 server 块,server_name 写准确,不要写成 localhost 或 _。
  3. 可以再写一个默认 server 块,拦截没有匹配域名的直接 IP 访问,避免陌生域名解析到这台机器后看到别人的站点:
server {
    listen 80 default_server;
    server_name _;
    return 444;
}

五、改完配置必须先测试再重载

每次改完都按这个顺序做,不要直接重启:

sudo nginx -t
sudo systemctl reload nginx
curl -I http://blog.example.com/
curl -I http://api.example.com/

nginx -t 通过才会输出 syntax is ok 和 test is successful,不通过时 reload 不会生效,要先按报错行号改配置。reload 是平滑重载,不会断开已有连接;只有 Nginx 本身升级或主进程异常时才需要 restart。

六、常见 502 Bad Gateway 排查清单

反向代理新手最常遇到 502,按这个顺序查,基本都能定位:

  1. 后端真的在跑吗?ss -tlnp | grep 3000 或 curl http://127.0.0.1:3000/,先在服务器本机确认后端端口能通,再谈 Nginx。
  2. 端口写错了吗?对照后端实际监听端口和 proxy_pass 里的端口,3000 写成 3001 就会 502。
  3. 后端只监听了 127.0.0.1 还是 0.0.0.0?反向代理走本机回环时用 127.0.0.1 就够,但如果后端在另一台机器,要写那台机器的内网 IP,并放行对应端口。
  4. 看 Nginx 错误日志,不要只看浏览器:sudo tail -n 50 /var/log/nginx/error.log,里面会明确写是 connection refused(后端没起)、timeout(后端太慢或防火墙拦截)还是 no live upstreams。
  5. 超时问题:后端接口本来就慢时,适当放宽 proxy_connect_timeout 5s;、proxy_read_timeout 60s;,而不是无限调大掩盖慢接口。
  6. WebSocket 或长连接场景:除了上面几行,还要加 proxy_set_header Upgrade $http_upgrade; 和 proxy_set_header Connection "upgrade";,否则握手会失败。

七、总结

反向代理的核心就三步:Nginx 监听 80/443 对外;server_name 按域名分流;location 里用 proxy_pass 转给后端并带上真实请求头。把这套流程跑通后,再给每个域名配 HTTPS(listen 443 ssl; 加证书路径),一台服务器跑五六个小网站也完全够用。记住一条铁律:改配置先 nginx -t,再 reload,出问题先看 error.log,不要凭感觉反复重启。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。