许多人第一次折腾 VPS 搭建自己的服务时,都会遇到一个问题:应用跑在 127.0.0.1:8080 或 Docker 映射的某个随机端口上,发给朋友根本没法体面地访问。

反向代理的核心任务就是充当流量管家:对外监听标准的 80/443 端口,根据不同的访问域名,把请求精准分发给后台对应的各个业务端口。

这篇笔记整理了 Nginx 从零安装、模块化站点配置(conf.d 拆分)、配置语法检查与热重载,以及单台服务器托管多个域名的实践流程。


什么是反向代理:为什么要用它

很多新手被“正向代理”和“反向代理”绕晕,其实用一个生活中的比喻立刻就能明白:

【外界访客 / 浏览器】
        │
        ▼ 访问 https://blog.0000996.xyz
┌───────────────────────────────────────────────────────┐
│              🏢 你的云服务器 (VPS)                      │
│                                                       │
│   💁 Nginx(大楼前台总机)                              │
│         │                                             │
│         ├─ 听到找 "blog"  ──► 转接给工位 A (:8090 Halo) │
│         ├─ 听到找 "pan"   ──► 转接给工位 B (:5244 AList)│
│         └─ 听到找 "api"   ──► 转接给工位 C (:5321 接口) │
└───────────────────────────────────────────────────────┘
  • 大白话:Nginx 就是你服务器里唯一的「大楼前台总机」。
  • 外面的访客只跟前台打交道(只记域名,永远走标准的 80/443 端口);
  • 前台根据访客报出的域名,在服务器内网默默把请求转交给对应的小黑屋工位(Halo 博客、AList 网盘、内部 API);
  • 外界根本不知道你的服务跑在哪个具体端口上,既优雅、又极其安全!

前置准备工作

  • [ ] 一台云服务器(VPS):拥有 root 登录权限;
  • [ ] 一个解析好的域名:例如将 blog.example.com 或 api.example.com 的 A 记录指向你的服务器 IP;
  • [ ] 一个已经跑在本地端口的服务:
  • 比如 Docker 跑的 Halo 博客(127.0.0.1:8090)或 AList 网盘(127.0.0.1:5244);
  • [ ] 云厂商控制台放行 80 和 443:在腾讯云/阿里云/AWS 网页安全组中,确保允许外网访问 80/tcp 和 443/tcp。

安装 Nginx 并验证运行状态

💻 【你本地的电脑】 打开终端连接你的服务器,进入 服务器端:。

粘贴执行以下官方标准安装与开机自启命令:

# 1. 刷新仓库并安装 Nginx
export DEBIAN_FRONTEND=noninteractive
apt update && apt install -y nginx

# 2. 启动服务并加入开机自启
systemctl enable --now nginx

# 3. 检查 Nginx 运行状态与版本
nginx -v
systemctl is-active nginx
  • ✅ 成功标志:终端输出显示 nginx version: nginx/1.x.x,且最后一行明确返回 active。

💡 防冲突小提醒:如果你服务器上装了 1Panel 或宝塔面板,且之前已经在面板里安装了 OpenResty,请先运行 ss -tulpn | grep :80 看一眼 80 端口是否已被占用。未占用的裸机直接跑上述命令即可。


合理的配置目录结构(conf.d 模块化管理)

很多新手改崩 Nginx,就是因为一上来就去动 /etc/nginx/nginx.conf,结果改得面目全非无法还原。

工业界标准的最佳实践是模块化管理:

目录路径 它的职责与角色 正确使用法则
/etc/nginx/sites-available/ 【配置草稿箱】:存放所有站点的独立配置文件 新建、修改站点配置一律在这里操作
/etc/nginx/sites-enabled/ 【正式生效箱】:只放生效站点的快捷方式(软链接) 绝不在里面新建文件,只用 ln -sf 从草稿箱链接过来
/etc/nginx/nginx.conf 【底层总发动机】:系统级总配置 新手碰都不要碰,保持官方默认

编写反向代理站点配置文件

这个配置是经过无数线上高并发业务验证过的黄金模板,原生内置了:
1. 真实访客 IP 透传:后端程序能拿到访客真实 IP,而不是全显示 127.0.0.1;
2. 大文件上传放行:默认放行 100MB 大文件,彻底告别传图报 413 Request Entity Too Large;
3. WebSocket 实时通信:后台实时日志、通知提醒秒级推送不卡死;
4. 长连接超时调优:防止发布大长文或备份时被 Nginx 提前掐断连接(报 504)。

服务器端: 先定义你的两个核心变量(替换为你自己的域名和后端内部端口):

MY_DOMAIN="api.example.com"
UPSTREAM_PORT="8090"

接着,直接整段复制执行以下自包含写入脚本(绝不需要手动碰 vim):

# 1. 写入独立的站点反代配置文件
cat << EOF > /etc/nginx/sites-available/${MY_DOMAIN}.conf
server {
    listen 80;
    listen [::]:80;
    server_name ${MY_DOMAIN};

    # 放行大文件上传(根据需要调大,如 100M)
    client_max_body_size 100M;

    location / {
        # 内部转接核心指令
        proxy_pass http://127.0.0.1:${UPSTREAM_PORT};

        # 核心请求头透传(让后端感知真实的访客与协议)
        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;

        # WebSocket 长连接双向保活支持
        proxy_http_version 1.1;
        proxy_set_header Upgrade \$http_upgrade;
        proxy_set_header Connection "upgrade";

        # 调优连接与读取超时时间(秒)
        proxy_connect_timeout 60s;
        proxy_read_timeout 120s;
        proxy_send_timeout 120s;
    }
}
EOF

# 2. 检查文件是否落地成功
ls -lh /etc/nginx/sites-available/${MY_DOMAIN}.conf
  • ✅ 成功标志:终端显示 /etc/nginx/sites-available/你的域名.conf 已成功创建。

语法检查与安全热重载

配置文件写好了,现在我们把它推入生效箱,并执行至关重要的语法安全体检。

服务器端: 粘贴执行以下激活与检查命令:

# 1. 创建快捷方式(软链接)到生效目录
ln -sf /etc/nginx/sites-available/${MY_DOMAIN}.conf /etc/nginx/sites-enabled/

# 2. 顺手清理掉默认的“Welcome to nginx”占位网页(避免冲突)
rm -f /etc/nginx/sites-enabled/default

# 3. 核心安全气囊:Nginx 语法预检
nginx -t
  • ✅ 成功标志:终端屏幕必须打出这两行绿色通过指标:
    text
    nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
    nginx: configuration file /etc/nginx/nginx.conf test is successful

只要看到 test is successful,立刻放心地让 Nginx 平滑重载:

systemctl reload nginx
  • 🗣️ 大白话:reload 是优雅热重载,旧的连接不会断开,新的配置瞬间生效,完全不需要先 stop 再 start!

为站点配置 HTTPS 加密访问

现在你的域名通过 HTTP 已经可以正常访问了,但现代网站必须带小绿锁(HTTPS)。根据你的架构选择以下任意一种:

🌟 方案 A:Cloudflare 边缘极速小黄云(小白首选,零运维)

如果你的域名托管在 Cloudflare,这是全世界最优雅省心的方式:
1. 💻 【浏览器】 打开 Cloudflare 仪表盘,找到你的域名 DNS 解析;
2. 确保你的域名 A 记录打开了橙色小云朵(已代理);
3. 点击左侧菜单 「SSL/TLS」,加密模式选择 「Flexible(灵活)」 或 「Full(完全)」;
4. 🏁 搞定! 你的 Nginx 服务器内部完全不需要装任何证书,Cloudflare 全球边缘 CDN 会自动为访客提供全球顶级免费 HTTPS 绿锁!


🛡️ 方案 B:Certbot 官方全自动证书(不走 CDN 或纯直连推荐)

如果你没用 Cloudflare,或者想在服务器本地生成纯正的 Let’s Encrypt 证书:

服务器端: 一行命令安装 Certbot 并让它自动配置 Nginx:

# 1. 安装 Certbot 自动化工具
apt install -y certbot python3-certbot-nginx

# 2. 一键自动申请证书并自动改写 Nginx 为 HTTPS(将命令里的域名换成你的)
certbot --nginx -d ${MY_DOMAIN} --non-interactive --agree-tos --register-unsafely-without-email --redirect
  • ✅ 成功标志:Certbot 输出 Congratulations! Successfully deployed certificate for ...,它会自动把 HTTP 访问 301 重定向到 HTTPS!
  • 💡 自动续期保障:Certbot 会自动注册 systemd 定时器,到期前 30 天静默自动续签,终身免维护。

多域名多站点共存配置

很多小白最困惑的一点:“我手里只有一台便宜 VPS,但我想同时挂一个博客、一个网盘、还有一个图床,端口全是 80/443,会不会打架?”

答案是:完全不会!Nginx 最擅长的就是这个。

你只需要按下面的结构,为每一个服务建一个独立的 .conf 文件:

/etc/nginx/sites-available/
├── blog.0000996.xyz.conf   ──► 转给 127.0.0.1:8090 (Halo博客)
├── pan.0000996.xyz.conf    ──► 转给 127.0.0.1:5244 (AList网盘)
└── img.0000996.xyz.conf    ──► 转给 127.0.0.1:8080 (图床服务)

每次想加新网站:
1. 回到【第 3 步】,把 MY_DOMAIN 和 UPSTREAM_PORT 换成新的;
2. 执行写入脚本;
3. 回到【第 4 步】,ln -sf 链接并执行 nginx -t;
4. systemctl reload nginx!
几秒钟之内,新域名瞬间上线,老网站业务丝毫不受影响!🚀


新手常见报错与排查

异常现象 真实根因 对应一秒救命招式
浏览器提示 502 Bad Gateway Nginx 活得好好的,但后端小黑屋里的服务挂了或端口填错 1. 检查内部端口:在服务器运行 curl -I http://127.0.0.1:你的端口;
2. 检查 Docker 容器:docker ps 看看对应容器是不是退出了(Exited)。
浏览器提示 连接超时 (Timed Out) 云厂商控制台外部门禁没放行 检查【准备清单】,去云服务器控制台安全组核对 80 和 443 端口是否处于「允许」状态。
执行 nginx -t 报错 syntax error 配置文件里少写了分号 ; 或大括号不闭合 报错信息会明确指明出问题的行号(例如 line 15),使用 cat -n /etc/nginx/sites-available/xxx.conf 对照行号补上分号即可。
上传稍大的图片或文件提示 413 Too Large Nginx 默认限制上传不能超过 1MB 检查配置里是否有 client_max_body_size 100M;,改好后记得 systemctl reload nginx。
提示 Address already in use 80 端口被占 Apache 或旧的进程抢占了端口 运行 lsof -i :80 或 ss -tulpn | grep :80,找到占用进程的 PID 并 kill 掉,再重启 Nginx。