Windows Server 使用 Nginx 反向代理实现域名访问内网 Gradio 应用

前言

在开发机器学习应用时,我们常常会遇到这样的场景:Gradio 应用运行在本地带 GPU 的服务器上,通过 SSH 隧道映射到云服务器,但访问时需要带上端口号(如 http://域名:7863),这样既不美观也不便于分享。

本文将介绍如何在 Windows Server 上使用 Nginx 反向代理,实现通过标准 80 端口(即直接使用域名 http://域名)访问内网的 Gradio 应用。

架构说明

应用架构:

  • 本地 GPU 服务器:运行 Gradio 应用(7863 端口)

  • SSH 隧道:将本地 7863 端口映射到云服务器 7863 端口

  • 云服务器:使用 Nginx 将 80 端口请求转发到本地 7863 端口

  • 用户访问:通过域名直接访问(无需端口号)

    用户浏览器 → 域名:80 → Nginx (云服务器) → localhost:7863 → SSH隧道 → 本地GPU服务器

为什么选择 Nginx 反向代理而不是直接映射到 80 端口?

  1. 权限问题:80 端口通常需要管理员权限,SSH 隧道直接映射可能受限
  2. 端口冲突:80 端口可能被 IIS 等服务占用
  3. 扩展性强:便于后续添加 HTTPS、负载均衡、缓存等功能
  4. 稳定安全:Nginx 可以处理更多的并发连接,提供更好的性能

环境准备

  • 云服务器:腾讯云 Windows Server(IP: 101.34.247.99)
  • 域名:www.instant3d.cloud(已解析到云服务器 IP)
  • 本地服务器:运行 Gradio 应用(7863 端口)
  • SSH 隧道:autossh 建立的反向隧道

步骤一:下载并安装 Nginx

1.1 下载 Nginx

访问 Nginx 官网:http://nginx.org/en/download.html

下载最新的 Stable version(稳定版),例如 nginx/Windows-1.24.0

1.2 解压安装

将下载的压缩包解压到 C:\nginx 目录

目录结构应该如下:

复制代码
C:\nginx\
├── conf\
│   └── nginx.conf
├── html\
├── logs\
└── nginx.exe

步骤二:配置 Nginx 反向代理

2.1 编辑配置文件

打开 C:\nginx\conf\nginx.conf,替换为以下完整配置:

nginx 复制代码
#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    # Gradio 应用反向代理配置
    server {
        listen       80;
        server_name  www.instant3d.cloud instant3d.cloud;

        #charset koi8-r;
        #access_log  logs/host.access.log  main;

        location / {
            proxy_pass http://127.0.0.1:7863;
            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;
            
            # Gradio WebSocket 支持(重要!)
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            
            # 超时设置
            proxy_connect_timeout 60s;
            proxy_send_timeout 60s;
            proxy_read_timeout 60s;
        }

        # redirect server error pages to the static page /50x.html
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

2.2 配置说明

关键配置项解释:

  • listen 80:监听 80 端口(HTTP 默认端口)
  • server_name:配置你的域名,支持多个域名
  • proxy_pass http://127.0.0.1:7863:将请求转发到本地 7863 端口
  • proxy_http_version 1.1UpgradeConnection 头:支持 WebSocket 连接,这对 Gradio 应用至关重要
  • 超时设置:防止长时间请求被断开

步骤三:检查并释放 80 端口

3.1 检查端口占用

打开 PowerShell,执行:

powershell 复制代码
netstat -ano | findstr :80

3.2 如果 IIS 占用了 80 端口

  1. 打开"服务器管理器" → "工具" → "IIS 管理器"
  2. 找到默认网站
  3. 右键 → "编辑绑定" → 修改端口或停止网站

步骤四:配置 Windows 防火墙

以管理员身份打开 PowerShell,执行:

powershell 复制代码
New-NetFirewallRule -DisplayName "Allow HTTP Port 80" -Direction Inbound -LocalPort 80 -Protocol TCP -Action Allow

成功后会显示防火墙规则的详细信息。

或者通过图形界面添加:

  1. 打开"Windows Defender 防火墙"
  2. 点击"高级设置"
  3. 选择"入站规则" → "新建规则"
  4. 类型选择"端口" → 协议选择"TCP" → 端口填写"80"
  5. 操作选择"允许连接"
  6. 应用范围全部勾选(域、专用、公用)
  7. 命名为"Allow HTTP Port 80"

步骤五:配置腾讯云安全组

5.1 登录腾讯云控制台

访问:https://console.cloud.tencent.com/

5.2 配置安全组规则

  1. 进入"云服务器" → "实例"
  2. 找到你的服务器实例
  3. 点击"安全组"标签
  4. 点击"配置规则"
  5. 在"入站规则"中点击"添加规则"
  6. 填写以下信息:
    • 类型:自定义
    • 来源:0.0.0.0/0
    • 协议端口:TCP:80
    • 策略:允许
  7. 点击"完成"保存

步骤六:启动 Nginx

6.1 测试配置文件

在 PowerShell 中执行:

powershell 复制代码
cd C:\nginx
.\nginx -t

如果看到以下输出,说明配置正确:

复制代码
nginx: the configuration file C:\nginx/conf/nginx.conf syntax is ok
nginx: configuration file C:\nginx/conf/nginx.conf test is successful

6.2 启动 Nginx

powershell 复制代码
.\nginx

注意:在 PowerShell 中直接执行会让窗口卡住,这是正常的。你可以:

  • 直接关闭窗口(Nginx 会继续运行)

  • 或按 Ctrl+C 后用后台方式启动:

    powershell 复制代码
    Start-Process -FilePath "C:\nginx\nginx.exe" -WindowStyle Hidden

6.3 验证 Nginx 运行状态

powershell 复制代码
tasklist | findstr nginx

应该看到两个进程:

复制代码
nginx.exe                     2456 RDP-Tcp#0                  2        704 K
nginx.exe                     1428 RDP-Tcp#0                  2      1,432 K

6.4 检查端口监听

powershell 复制代码
netstat -ano | findstr :80
netstat -ano | findstr :7863

正常情况下应该看到:

复制代码
TCP    0.0.0.0:80             0.0.0.0:0              LISTENING       1428
TCP    0.0.0.0:7863           0.0.0.0:0              LISTENING       5860
TCP    10.0.4.10:7863         112.17.79.157:5303     ESTABLISHED     5860

步骤七:配置 SSH 隧道(如果还没有)

在你的本地 GPU 服务器上执行:

bash 复制代码
autossh -M 0 -N -R 0.0.0.0:7863:localhost:7863 -o ServerAliveInterval=60 -o ServerAliveCountMax=3 Administrator@101.34.247.99

参数说明:

  • -M 0:不使用监控端口
  • -N:不执行远程命令
  • -R 0.0.0.0:7863:localhost:7863:反向隧道,将本地 7863 映射到云服务器 7863
  • -o ServerAliveInterval=60:每 60 秒发送心跳包
  • -o ServerAliveCountMax=3:最多允许 3 次心跳失败

步骤八:测试访问

8.1 本地测试

在云服务器上打开浏览器,访问:

复制代码
http://localhost

8.2 外网访问

在任何地方打开浏览器,访问:

复制代码
http://www.instant3d.cloud

如果能看到 Gradio 应用界面,恭喜配置成功!🎉

Nginx 常用管理命令

powershell 复制代码
cd C:\nginx

# 测试配置文件
.\nginx -t

# 启动 Nginx
.\nginx

# 重新加载配置(不中断服务)
.\nginx -s reload

# 停止 Nginx
.\nginx -s stop

# 快速停止 Nginx
.\nginx -s quit

# 查看 Nginx 进程
tasklist | findstr nginx

# 强制结束 Nginx 进程
taskkill /F /IM nginx.exe

设置 Nginx 开机自启(强烈推荐)

设置开机自启后,云端服务器重启时 Nginx 会自动启动,无需手动干预。

方法一:使用批处理文件

  1. 创建 C:\nginx\start_nginx.bat 文件:
batch 复制代码
@echo off
cd C:\nginx
start nginx.exe
  1. 创建 Windows 任务计划:
    • 打开"任务计划程序"
    • 创建基本任务
    • 触发器选择"启动时"
    • 操作选择"启动程序"
    • 程序路径:C:\nginx\start_nginx.bat
    • 勾选"使用最高权限运行"

方法二:使用 NSSM(强烈推荐)⭐

NSSM 可以将任何程序注册为 Windows 服务,更加稳定可靠,服务器重启后自动运行。

1. 下载 NSSM

访问:https://nssm.cc/download

下载后解压到任意目录,例如 C:\nssm

2. 安装为 Windows 服务

以管理员身份运行 PowerShell:

powershell 复制代码
cd C:\nssm\win64

# 安装 Nginx 服务
.\nssm install nginx "C:\nginx\nginx.exe"

# 设置工作目录
.\nssm set nginx AppDirectory "C:\nginx"

# 设置为自动启动
.\nssm set nginx Start SERVICE_AUTO_START

# 启动服务
.\nssm start nginx

3. 管理 Nginx 服务

powershell 复制代码
# 启动服务
.\nssm start nginx

# 停止服务
.\nssm stop nginx

# 重启服务
.\nssm restart nginx

# 查看状态
.\nssm status nginx

# 卸载服务(需要先停止)
.\nssm stop nginx
.\nssm remove nginx confirm

也可以通过 Windows 服务管理器管理:

  • 打开"服务"(services.msc)
  • 找到 "nginx" 服务
  • 右键可以启动/停止/重启

常见问题排查

1. 访问域名显示 502 Bad Gateway

可能原因:

  • SSH 隧道未建立或已断开
  • 本地 Gradio 应用未启动
  • 7863 端口未监听

解决方法:

powershell 复制代码
# 检查 7863 端口
netstat -ano | findstr :7863

# 查看 Nginx 错误日志
type C:\nginx\logs\error.log

2. 访问域名显示 504 Gateway Timeout

可能原因:

  • Nginx 超时设置太短
  • Gradio 应用响应慢

解决方法:

增加 nginx.conf 中的超时时间:

nginx 复制代码
proxy_connect_timeout 120s;
proxy_send_timeout 120s;
proxy_read_timeout 120s;

3. WebSocket 连接失败

可能原因:

  • 缺少 WebSocket 相关配置

解决方法:

确保 nginx.conf 中包含以下配置:

nginx 复制代码
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

4. 域名无法访问

排查步骤:

  1. 检查域名解析:
powershell 复制代码
nslookup www.instant3d.cloud
  1. 检查腾讯云安全组是否开放 80 端口

  2. 检查 Windows 防火墙规则

  3. 在服务器本地测试 http://localhost 是否正常

5. Nginx 无法启动

查看错误日志:

powershell 复制代码
type C:\nginx\logs\error.log

常见错误:

  • 端口被占用:使用 netstat -ano | findstr :80 检查
  • 配置文件语法错误:使用 .\nginx -t 检查

进阶优化

1. 添加 HTTPS 支持

申请 SSL 证书后,修改 nginx.conf:

nginx 复制代码
server {
    listen       443 ssl;
    server_name  www.instant3d.cloud instant3d.cloud;

    ssl_certificate      cert/your_cert.crt;
    ssl_certificate_key  cert/your_cert.key;
    
    ssl_session_cache    shared:SSL:1m;
    ssl_session_timeout  5m;
    ssl_ciphers  HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers  on;

    location / {
        proxy_pass http://127.0.0.1:7863;
        # ... 其他配置同上
    }
}

# HTTP 重定向到 HTTPS
server {
    listen       80;
    server_name  www.instant3d.cloud instant3d.cloud;
    return 301 https://$server_name$request_uri;
}

2. 启用 Gzip 压缩

在 http 块中添加:

nginx 复制代码
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml;

3. 添加访问日志

nginx 复制代码
access_log  logs/access.log  main;

4. 限制请求频率

nginx 复制代码
http {
    limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;
    
    server {
        location / {
            limit_req zone=mylimit burst=20;
            # ... 其他配置
        }
    }
}

总结

通过 Nginx 反向代理,我们成功实现了:

  1. ✅ 使用标准 80 端口访问(无需端口号)
  2. ✅ 域名直接访问,更加美观和专业
  3. ✅ 支持 WebSocket,Gradio 功能完整
  4. ✅ 便于后续扩展(HTTPS、负载均衡等)
  5. ✅ 稳定可靠的生产环境方案

这个方案不仅适用于 Gradio 应用,也适用于其他需要端口映射的 Web 应用。

服务器重启后的操作指南

场景一:本地 GPU 服务器重启

云端完全不受影响! 只需在本地服务器上:

  1. 重启 Gradio 应用(监听 7863 端口)

  2. 重新建立 SSH 隧道

    bash 复制代码
    autossh -M 0 -N -R 0.0.0.0:7863:localhost:7863 -o ServerAliveInterval=60 -o ServerAliveCountMax=3 Administrator@101.34.247.99

云端的 Nginx 一直在运行,等待 7863 端口的数据,无需任何操作。

场景二:云端服务器重启

根据是否设置了 Nginx 开机自启:

如果已设置开机自启(使用 NSSM)

  • 什么都不用做! Nginx 会自动启动
  • 验证:访问 http://www.instant3d.cloud 确认服务正常

如果未设置开机自启

  • 需要手动启动 Nginx:

    powershell 复制代码
    cd C:\nginx
    .\nginx

    或后台启动:

    powershell 复制代码
    Start-Process -FilePath "C:\nginx\nginx.exe" -WindowStyle Hidden

建议

强烈建议使用 NSSM 设置 Nginx 开机自启,这样:

  • 云端服务器重启后自动恢复服务
  • 无需手动干预,提高可用性
  • 可通过 Windows 服务管理器统一管理
  • 只需 5 分钟一次性配置,一劳永逸

快速诊断命令

遇到问题时,可以使用以下命令快速诊断:

powershell 复制代码
# 检查 Nginx 是否运行
tasklist | findstr nginx

# 检查端口监听状态
netstat -ano | findstr :80
netstat -ano | findstr :7863

# 查看 Nginx 错误日志
type C:\nginx\logs\error.log

# 测试本地访问
curl http://localhost
相关推荐
warton881 天前
ubuntu24.04 安装mysql8.0.36
linux·运维·mysql
运维有小邓@1 天前
如何实现基于角色的访问控制?
运维·网络
范纹杉想快点毕业1 天前
嵌入式通信核心架构:从状态机、环形队列到多协议融合
linux·运维·c语言·算法·设计模式
小龙1 天前
【Git 报错解决】SSH 公钥认证失败(`Permission denied (publickey)`)
运维·git·ssh
白驹过隙^^1 天前
VitrualBox及ubuntu系统安装
linux·运维·ubuntu
可爱又迷人的反派角色“yang”1 天前
k8s(一)
linux·运维·网络·云原生·容器·kubernetes
上去我就QWER1 天前
什么是反向代理?
后端·nginx
可爱又迷人的反派角色“yang”1 天前
CICD持续集成Ruo-Yi项目
linux·运维·网络·ci/cd·docker·容器
满天星83035771 天前
【C++】特殊类设计
c++·windows