一台服务器只放一个网站太浪费。Nginx 可以让多个域名共用一台机器、共用一个 80/443 端口,还能把请求转发给后端的不同应用(Node、Java、Docker 容器、游戏面板等)。
这篇讲透虚拟主机(多站点)和反向代理两件事。
一台机器搞定多个站点,配置要够用。财富云计算 的云服务器提供多种规格;做内网服务、测试环境、游戏服务端可选 NAT 型(无独立公网 IP,价格比独立 IP 机型省一半以上,通过端口映射对外提供服务)。
一、Nginx 是怎么区分不同网站的
浏览器访问 a.com 和 b.com,如果解析到同一个 IP,请求包里的 IP 是一样的。区分靠的是 HTTP 请求头里的 Host 字段。
GET / HTTP/1.1
Host: a.com ← Nginx 靠这个决定用哪个 server 块所以多站点配置的核心就是:多个 server 块,server_name 不同。
匹配规则(当请求的 Host 匹配不到时):
- 精确匹配
server_name a.com - 通配符
*.a.com - 正则
~^www\d+\.a\.com$ - 该端口下的第一个 server 块(默认站点)
- 显式指定:
listen 80 default_server;
建议显式配一个默认站点兜底,避免意外命中:
server {
listen 80 default_server;
server_name _;
return 444; # 直接关闭连接,不响应
}444 是 Nginx 特有的状态码:立即断开,不返回任何内容,很适合对付乱扫的扫描器。
二、多站点配置实战
目录规划
/var/www/
├── site-a/ # a.com
│ └── index.html
├── site-b/ # b.com
│ └── index.html
└── blog/ # blog.c.com站点 A
mkdir -p /var/www/site-a
echo "<h1>Site A</h1>" > /var/www/site-a/index.html
nano /etc/nginx/sites-available/site-aserver {
listen 80;
server_name a.com www.a.com;
root /var/www/site-a;
index index.html;
access_log /var/log/nginx/site-a.access.log;
error_log /var/log/nginx/site-a.error.log;
location / {
try_files $uri $uri/ =404;
}
}站点 B(带 PHP)
server {
listen 80;
server_name b.com www.b.com;
root /var/www/site-b;
index index.php index.html;
access_log /var/log/nginx/site-b.access.log;
error_log /var/log/nginx/site-b.error.log;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\. {
deny all;
}
}启用:
ln -s /etc/nginx/sites-available/site-a /etc/nginx/sites-enabled/
ln -s /etc/nginx/sites-available/site-b /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx拆分配置文件的好处
- 每个站点独立,改一个不影响其他
- 出问题容易定位
- 可以单独给某站点加 HTTPS、限速、访问控制
- 日志分开,统计方便
三、反向代理:把请求转发给后端应用
反向代理 = 用户访问 Nginx,Nginx 再去找真正的服务要数据,返回给用户。用户不知道后端是谁。
典型用途:
| 用途 | 说明 |
|---|---|
| 隐藏后端 | 后端只监听 127.0.0.1,外部访问不到,更安全 |
| 统一入口 | 多个服务共用一个 80/443 |
| HTTPS 卸载 | Nginx 处理加密,后端跑 HTTP |
| 负载均衡 | 分发到多台后端 |
| 缓存加速 | 缓存后端响应 |
| 跨域解决 | 前端同源访问 |
最基础的反代
server {
listen 80;
server_name app.example.com;
location / {
proxy_pass http://127.0.0.1:3000;
# 传递真实信息给后端(非常重要,否则后端看到的都是 127.0.0.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_pass 的斜杠陷阱(新手高频坑):
location /api/ {
proxy_pass http://127.0.0.1:3000; # 保留 /api/ 前缀:/api/user → :3000/api/user
}
location /api/ {
proxy_pass http://127.0.0.1:3000/; # 去掉 /api/ 前缀:/api/user → :3000/user
}有没有末尾的斜杠,决定了 URI 是否被替换。 记住这条就不会踩坑了。
完整反代配置(生产可用)
upstream backend {
server 127.0.0.1:3000;
keepalive 32;
}
server {
listen 443 ssl http2;
server_name app.example.com;
ssl_certificate /etc/letsencrypt/live/app.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/app.example.com/privkey.pem;
location / {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Connection ""; # 配合 keepalive
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_connect_timeout 10s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# 缓冲
proxy_buffering on;
proxy_buffer_size 8k;
proxy_buffers 16 8k;
}
# WebSocket 支持
location /ws/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 3600s;
}
}四、负载均衡
一个 upstream 里写多台后端:
upstream app_pool {
# 默认轮询
server 127.0.0.1:3001;
server 127.0.0.1:3002;
server 127.0.0.1:3003;
}调度策略
upstream app_pool {
# 1. 轮询(默认)
server 10.0.0.1:8080;
server 10.0.0.2:8080;
# 2. 加权轮询
server 10.0.0.1:8080 weight=3; # 3/4 的请求
server 10.0.0.2:8080 weight=1; # 1/4 的请求
# 3. IP 哈希(同一客户端固定到同一台,解决 session 问题)
ip_hash;
# 4. 最少连接
least_conn;
}健康检查(被动)
upstream app_pool {
server 10.0.0.1:8080 max_fails=3 fail_timeout=30s;
server 10.0.0.2:8080 max_fails=3 fail_timeout=30s;
server 10.0.0.3:8080 backup; # 备用,其他都挂了才上
}主动健康检查(定期探测)需要 Nginx Plus 或第三方模块;开源版可以用 max_fails 被动剔除。会话保持
有状态应用(依赖本地 session)用 ip_hash;更好的做法是把 session 存到 Redis,后端无状态,怎么分发都行。
五、实战:一台服务器跑多个不同类型的应用
场景:
blog.com→ 静态 + PHP(Typecho)api.com→ Node.js 跑在 3000admin.com→ Java 跑在 8080game.com→ 游戏面板跑在 8081
# blog.com —— PHP 站点
server {
listen 443 ssl http2;
server_name blog.com;
ssl_certificate /etc/letsencrypt/live/blog.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/blog.com/privkey.pem;
root /var/www/blog;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
}
}
# api.com —— Node.js
server {
listen 443 ssl http2;
server_name api.com;
ssl_certificate /etc/letsencrypt/live/api.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/api.com/privkey.pem;
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;
}
}
# admin.com —— Java(带长超时)
server {
listen 443 ssl http2;
server_name admin.com;
ssl_certificate /etc/letsencrypt/live/admin.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/admin.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:8080;
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_read_timeout 120s;
# 只允许内网访问管理后台
allow 192.168.1.0/24;
deny all;
}
}
# game.com —— 面板
server {
listen 443 ssl http2;
server_name game.com;
ssl_certificate /etc/letsencrypt/live/game.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/game.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:8081;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_read_timeout 3600s;
}
}
# 统一 HTTP 跳转
server {
listen 80 default_server;
server_name _;
return 301 https://$host$request_uri;
}六、反代场景的几个坑
1)后端拿不到真实 IP
必须设 X-Real-IP / X-Forwarded-For,且后端程序要读这个头:
- Nginx 层再加:
set_real_ip_from 上游IP; real_ip_header X-Forwarded-For; - PHP:
$_SERVER['HTTP_X_FORWARDED_FOR'] - Node(Express):
app.set('trust proxy', true) - 日志格式里改用
$http_x_forwarded_for
2)502 Bad Gateway
tail -50 /var/log/nginx/error.log
# 常见:
# connect() failed (111: Connection refused) → 后端没起
# connect() to 127.0.0.1:3000 failed (13: Permission denied) → SELinux 拦截SELinux 上允许 Nginx 发起网络连接:
setsebool -P httpd_can_network_connect 13)上传大文件失败
client_max_body_size 100m; # 在 server 或 http 块
proxy_read_timeout 300s;4)WebSocket 连不上
必须加 Upgrade 和 Connection 头(见上文配置)。
5)重定向循环
后端程序以为自己是 HTTP(因为反代用的是 HTTP),于是返回 HTTP 跳转,浏览器再请求,无限循环。
解决:传 X-Forwarded-Proto $scheme,并让后端识别。WordPress 等程序加:
if ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') {
$_SERVER['HTTPS'] = 'on';
}6)响应慢
proxy_buffering off; # 流式响应(SSE)需要关
proxy_request_buffering off;
proxy_read_timeout 300s;七、反代 + 缓存:给后端减负
http {
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=mycache:100m
max_size=1g inactive=60m use_temp_path=off;
}
server {
location / {
proxy_cache mycache;
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503;
proxy_cache_lock on;
proxy_cache_background_update on;
add_header X-Cache-Status $upstream_cache_status;
proxy_pass http://backend;
}
}响应头里会显示 X-Cache-Status: HIT / MISS / BYPASS,方便调试。
mkdir -p /var/cache/nginx
nginx -t && systemctl reload nginx八、用 include 组织配置
配置文件多了以后,把公共部分抽出来:
mkdir -p /etc/nginx/snippets/etc/nginx/snippets/proxy-headers.conf
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_connect_timeout 10s;
proxy_read_timeout 60s;/etc/nginx/snippets/ssl-params.conf
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:50m;
ssl_session_timeout 1d;
add_header Strict-Transport-Security "max-age=63072000" always;
add_header X-Content-Type-Options nosniff always;使用时:
server {
listen 443 ssl http2;
server_name api.com;
include snippets/ssl-params.conf;
ssl_certificate ...;
ssl_certificate_key ...;
location / {
proxy_pass http://127.0.0.1:3000;
include snippets/proxy-headers.conf;
}
}改一处,所有站点生效。
九、调试技巧
nginx -T | grep -A 20 "server_name api.com" # 查看最终生效的完整配置
nginx -t # 语法检查
tail -f /var/log/nginx/error.log给反代加调试头:
add_header X-Upstream $upstream_addr;
add_header X-Upstream-Time $upstream_response_time;
add_header X-Request-Time $request_time;curl -I https://api.com
# X-Upstream: 127.0.0.1:3000
# X-Upstream-Time: 0.052
# X-Request-Time: 0.055一眼看出请求转发到哪台后端、花了多久。
十、一台服务器能放多少个站点
没有硬性限制,取决于:
| 因素 | 影响 |
|---|---|
| 内存 | 每个 PHP-FPM / Java 进程都吃内存,是主要瓶颈 |
| CPU | 动态站点多的情况下 |
| 带宽 | 流量大的站点 |
| 磁盘 IO | 数据库读写频繁时 |
经验参考(2 核 4G):
- 静态站点:几十个没问题
- WordPress/Typecho 类的轻量站点:5~10 个
- Java/Node 应用:2~4 个(Java 尤其吃内存)
建议:数据库和 Web 分离、静态资源用缓存、给每个站点配 PHP-FPM 独立池并限制进程数,避免一个站点的流量把整机拖垮。
多站点部署对内存要求更高。财富云计算 的云服务器可按业务增长升级配置;若只是跑内网服务、开发测试、游戏服务端,NAT 型云服务器(无独立公网 IP,价格比带独立 IP 机型省一半以上)可以把预算更多留给内存和 CPU。
相关阅读:
- 《Nginx 安装与配置入门》
- 《免费 SSL 证书申请与 HTTPS 部署》
- 《域名解析与 DNS 记录详解》
- 《网站打开慢的排查流程》
延伸阅读
- 网站环境怎么选:LNMP 手动 / 宝塔面板 / Docker / 云开发
- 问卷表单系统搭建:SurveyKing / Formbricks,数据自己收
- 图床搭建:Lsky Pro / Lychee,自托管图片托管方案
- 邮件列表搭建:listmonk 自托管 Newsletter,把读者握在自己手里
- 文档站点搭建:MkDocs / VuePress / Docsify,产品文档与技术手册方案
- RSS 阅读器搭建:FreshRSS 自托管,把信息流拿回自己手里
- 短链接服务搭建:Shlink 自托管,链接数据自己掌握
- 网站状态监控页搭建:Uptime Kuma,服务器挂了第一时间知道

[...]空 Referer: 允许(浏览器直接访问场景按需)IP 黑白名单:发现恶意刷流量的 IP 直接封开启用量告警:超过阈值短信/邮件通知,被盗刷第一时间知道私有读 + 签名 URL:用户头像、订单附件这类敏感文件,用服务端生成带签名的临时链接(有效期几分钟),杜绝直接暴露上传安全:API 密钥只放服务器环境变量,别提交进 Git;密钥定期轮换。七、常见问题Q:搬迁后网站图片全挂?多半是数据库 URL[...]
2026-10-13 回复
[...]动态: www.example.com → 源站(只开 80/443 给 CDN)WordPress/Typecho 都有 CDN 插件,一键改静态资源地址,配合网站图片优化效果更明显。速度测试方法见网站速度测试工具与方法。CDN 是性价比最高的网站优化:一顿饭钱让全国访问都快一倍,还能藏住源站。配好缓存策略 + 源站保护,就是又安全又快的正经架构。需要现成的游戏云服务器,可以看看财富云计算:一[...]
2026-10-15 回复
[...]# 用 last/permanent 分清语义,配 error_log info 看跳转链完整 Web 防护见网站常见漏洞与基础防护和WAF 规则实战。七、速查表需求写法伪静态try_files $uri $uri/ /index.php?$query_string;HTTP→HTTPSreturn 301 https://$host$request_uri;www 跳主域return 301 h[...]
2026-10-15 回复
[...]MemoryMax=12G # 限额,保护其他服务个人网站(资源乞丐,但价值高)Typecho/WordPress/Halo 都行,LNMP 一套几百兆内存:数据库用 SQLite(更省)或 MySQL 小实例,选型见SQLite 与 MySQL 怎么选Typecho 搭建见用云服务器搭建 Typecho 博客Nginx 站点配置见Nginx 安装与配置入门网站和游戏服共用 N[...]
2026-10-18 回复
[...]4核16G照常有 公网IP:端口 才能进维度NAT 型独立 IPCPU / 内存 / 磁盘性能完全一致一致出站连接(你连别人)无限制无限制入站连接(别人连你)需端口映射IP 直连可映射端口数平台规则(通常 5-20)65535价格独立 IP 一半以下全价结论先行:对 90% 的个人用户场景,NAT 型和独立 IP 的体验差距只在「配置端口映射」这一步。二、完全无感的场景:映射[...]
2026-10-18 回复
[...]0 3 * tar -czf /backup/site_$(date +\%F).tar.gz /var/www/html -C /backup 2>/dev/null; rclone copy /backup/site_$(date +\%F).tar.gz remote:sitebackup/详细方案见网站迁移完整流程和rsync 同步与定时备份实战。六、安全三件套(小站也要装)[...]
2026-10-18 回复
[...]}反向代理配置见Nginx 反向代理与多站点,端口映射前提见NAT 端口映射完全指南。管理类服务(Kuma)务必加访问控制,见服务器端口安全。五、安全四件套(容器化也要装)容器不映射管理端口到公网:Kuma、数据库这类只走 Nginx 反代 + 访问控制。镜像来源可信:只用官方/知名社区镜像,别用来路不明的镜像(镜像里可以藏挖矿程序,见开源程序部署安全检查)。Docker socket 不给普通容[...]
2026-10-18 回复
[...]netsh advfirewall firewall add rule name="GameRange" dir=in action=allow protocol=UDP localport=26901-26903完整的 Windows 环境准备(远程桌面连接、运行库安装、SteamCMD 用法、开机自启、8 个常见坑)见:《Windows 云服务器开服通用前置教程》→ htt[...]
2026-10-18 回复
[...]}WebSocket 那三行别省,Wiki.js 的实时协作和搜索建议靠它。反向代理细节见Nginx 反向代理与多站点配置。3. 初始化:访问 https://wiki.yourdomain.com,管理员账号、存储引擎(本地或对象存储)、搜索引擎(PostgreSQL 够用)一路下一步。第一次就把管理员密码和备份策略设好。三、知识库怎么用才不荒废工具只是三分之一,另外三分之二是规矩:分类先于内容[...]
2026-10-18 回复
[...]}证书用 Let's Encrypt 免费申请,见免费 SSL 证书申请与 HTTPS 部署。反代细节见Nginx 反向代理与多站点配置。DOMAIN 环境变量必须和实际访问地址完全一致(协议 + 域名 + 端口),否则客户端同步会报错——这是自托管 Vaultwarden 第一大坑。四、客户端接入服务端跑起来后,各平台用官方 Bitwarden 客户端,登录时把服务器地址改成你的域名:平台客户端[...]
2026-10-18 回复
[...]}反代细节见Nginx 反向代理与多站点配置,证书见免费 SSL 证书申请与 HTTPS 部署。三、监控项配置:按这个清单加基础四件(每个站长都该有):监控项类型间隔说明网站首页HTTPS60s关键字匹配"你的品牌词",防"能打开但是挂马页"服务器 PingPing60s探活,不通就是机器/网络层出事SSH 端口TCP:2260s服务没挂但 SSH 不通 = 被墙或防火墙抽风数据库端口TCP:33[...]
2026-10-18 回复
[...]}证书见免费 SSL 证书申请与 HTTPS 部署,反通用配置见Nginx 反向代理与多站点配置。三、创建短链:CLI 和 APICLI 建链:# 生成一个随机短码[...]
2026-10-18 回复
[...]}反代见Nginx 反向代理与多站点配置,证书见免费 SSL 证书申请与 HTTPS 部署。三、SMTP:发信的发动机listmonk 本身不发信,它调度任务,真正发信靠 SMTP。三条路:方案成本适合注意第三方事务邮件服务(AWS SES、SendCloud、Mailgun)按量,很便宜生产环境首选需域名验证服务器自建 SMTP(Postfix/Exim)服务器成本有运维能力IP 信誉自己养,极[...]
2026-10-18 回复