feat(web): 移除 Docker 与反代部署,改为 Linux 业务服务并自带管理端托管

需求变更:Web 端只保留业务需求,反向代理交由另外的服务处理,
本项目仅提供 IIS / nginx 反代说明文档,不部署反代。

主要改动:
- web-server: 新增管理端静态托管(ADMIN_DIR、SPA 深链接回退),
  反代因此只需一条全匹配转发规则;新增 adminDir 配置项
- deploy/install.sh: 删除 nginx 安装与站点配置逻辑,改为原生 Linux
  服务部署(systemd → OpenRC → SysVinit → 后台进程四级降级),
  打印反代交接指引
- deploy/ctl.sh: 启停/状态/日志脚本
- deploy/proxy/: 新增反代说明文档(README.md、nginx.conf.example、
  web.config.example),标注上传上限与超时必须同步调整
- 删除 deploy/nginx/、web-server/admin/nginx.conf、Dockerfile、
  docker-compose.yml、.dockerignore
- scripts/package-release.sh: 锚定排除规则 + 产物完整性校验
- 文档同步:README.txt、DSH.md、project.yaml、tasks/008、tasks/010
This commit is contained in:
2026-09-15 01:25:19 +08:00
parent 653d9d168c
commit 8c76b0a599
17 changed files with 581 additions and 244 deletions
+10 -3
View File
@@ -8,8 +8,13 @@
# ---- 服务 ----
NODE_ENV=production
PORT=3000
# 仅监听本机,由 nginx 反向代理对外提供服务(不要直接暴露 Node 进程)
HOST=127.0.0.1
# 监听地址:
# 反代与后端同机 → 127.0.0.1(后端不直接对外暴露,推荐)
# 反代在别的机器 → 0.0.0.0,并用防火墙把该端口限制为仅反代来源可访问
HOST=0.0.0.0
# 管理端静态站点目录(本服务自带管理端页面,反代只需整体转发到本端口)
ADMIN_DIR=/opt/opendance/admin
# ---- 现有 MySQL / MariaDB 实例(本项目不安装、不管理数据库)----
DB_HOST=<existing-mysql-host>
@@ -24,7 +29,9 @@ DB_LOGGING=false
# ---- 文件存储 ----
# 需与 install.sh 的 STORAGE_DIR 一致,且服务用户可写
STORAGE_DIR=/var/lib/opendance/storage
# 单文件上传上限(字节),默认 512 MiB;nginx 的 client_max_body_size 需不小于此值
# 单文件上传上限(字节),默认 512 MiB。
# ★ 反向代理层的同名限制必须不小于此值(nginx client_max_body_size /
# IIS requestLimits),否则大模型上传会在代理层被拒(413)。
UPLOAD_MAX_BYTES=536870912
# ---- 可选的 Assimp(FBX/glTF 动作预处理)----
+34 -49
View File
@@ -2,9 +2,9 @@
# ============================================================
# OpenDance Studio Web 服务端 —— Linux 原生站点部署脚本
#
# 部署形态(不使用 Docker):
# nginx ── 静态托管管理端 + 反向代理 API
# └──▶ systemd 托管的 Node 进程(NestJS,仅监听 127.0.0.1)
# 部署形态(不使用 Docker、不部署反向代理):
# 本脚本只负责把 NestJS 业务服务跑起来(systemd / OpenRC / SysVinit / 后台进程)。
# 该服务自带管理端页面,反向代理由另外的服务负责,配置说明见 deploy/proxy/。
#
# 数据库仍是部署方提供的**现有 MySQL / MariaDB 实例**,本脚本不安装、不管理数据库。
#
@@ -16,8 +16,7 @@
# APP_DIR 安装目录(默认 /opt/opendance)
# SERVICE_USER 运行服务的系统用户(默认 opendance)
# STORAGE_DIR 上传文件目录(默认 /var/lib/opendance/storage)
# SERVER_NAME nginx server_name(默认 _)
# SKIP_NGINX=1 只装 API 服务,不配置 nginx
# PORT API 监听端口(默认 3000)
# ============================================================
set -euo pipefail
# 失败时打印出错行号,避免只看到半截输出
@@ -29,7 +28,6 @@ cd "$SRC_DIR"
APP_DIR="${APP_DIR:-/opt/opendance}"
SERVICE_USER="${SERVICE_USER:-opendance}"
STORAGE_DIR="${STORAGE_DIR:-/var/lib/opendance/storage}"
SERVER_NAME="${SERVER_NAME:-_}"
API_HOST="127.0.0.1"
API_PORT="${PORT:-3000}"
@@ -88,7 +86,7 @@ http_ok() {
}
# ---------- 0. 前置检查 ----------
[ "$(id -u)" -eq 0 ] || die "需要 root 权限(安装 systemd 服务与 nginx 站点)。
[ "$(id -u)" -eq 0 ] || die "需要 root 权限(安装系统服务、创建服务用户)。
请以 root 身份执行,例如: su -c 'bash deploy/install.sh' 或 sudo bash deploy/install.sh"
# 缺少 deploy/.env 时,若安装目录里已有上次安装留下的配置,直接复用。
@@ -385,46 +383,31 @@ if [ "$READY" -ne 1 ]; then
fi
log "API 已就绪:$(http_get "http://${API_HOST}:${API_PORT}/health" | head -c 200)"
# ---------- 5. nginx ----------
if [ "${SKIP_NGINX:-0}" = "1" ]; then
warn "SKIP_NGINX=1,跳过 nginx 配置。API 仅在 ${API_HOST}:${API_PORT} 提供。"
else
if ! command -v nginx >/dev/null 2>&1; then
warn "未安装 nginx,跳过站点配置。"
warn " 安装后重新执行本脚本,或手动把 deploy/nginx/opendance.conf 放到 nginx 配置目录。"
else
log "配置 nginx 站点"
NGINX_AVAILABLE=/etc/nginx/sites-available
NGINX_ENABLED=/etc/nginx/sites-enabled
# RHEL 系发行版没有 sites-available 约定
if [ ! -d "$NGINX_AVAILABLE" ]; then
NGINX_AVAILABLE=/etc/nginx/conf.d
NGINX_ENABLED=/etc/nginx/conf.d
fi
# ---------- 5. 反向代理(本脚本**不部署**,仅给出说明) ----------
# 需求变更:Web 端只负责业务服务,反向代理由另外的服务/团队提供。
# 本服务已自带管理端页面,因此反代只需把请求**整体转发**到本端口,
# 无需在代理层再托管静态文件、也无需配置 SPA 回退(服务端已处理)。
cat <<EOF
DEST="$NGINX_AVAILABLE/opendance.conf"
sed -e "s|__APP_DIR__|$APP_DIR|g" \
-e "s|__SERVER_NAME__|$SERVER_NAME|g" \
-e "s|__API_HOST__|$API_HOST|g" \
-e "s|__API_PORT__|$API_PORT|g" \
"$APP_DIR/deploy/nginx/opendance.conf" > "$DEST"
------------------------------------------------------------
反向代理说明(本脚本不部署反代)
------------------------------------------------------------
本服务已同时提供 API 与管理端页面,反代只需将请求整体转发至:
http://<本机地址>:${API_PORT}
if [ "$NGINX_ENABLED" != "$NGINX_AVAILABLE" ]; then
ln -sf "$DEST" "$NGINX_ENABLED/opendance.conf"
if [ -e "$NGINX_ENABLED/default" ]; then
rm -f "$NGINX_ENABLED/default"
log "已移除 nginx 默认站点(避免抢占 80 端口)"
fi
fi
健康检查(可用于反代的存活探测):http://<本机地址>:${API_PORT}/health
上传上限需在代理层同步放开(本服务为 $(( ${UPLOAD_MAX_BYTES:-536870912} / 1024 / 1024 )) MiB)
if nginx -t; then
systemctl reload nginx 2>/dev/null || systemctl restart nginx 2>/dev/null || nginx -s reload
log "nginx 已重载"
else
die "nginx 配置校验失败,请检查 $DEST"
fi
fi
fi
配置样例与完整说明:
deploy/proxy/nginx.conf.example nginx 站点配置
deploy/proxy/web.config.example IIS(ARR + URL Rewrite)配置
deploy/proxy/README.md IIS / nginx 反代说明文档
注意:若反代与后端不在同一台机器,需保持 HOST=0.0.0.0 并用防火墙限制来源;
若在同一台机器,建议把 HOST 改为 127.0.0.1。
------------------------------------------------------------
EOF
# ---------- 6. 完成 ----------
HOST_HINT="${DEPLOY_HOST:-<服务器IP>}"
@@ -456,11 +439,13 @@ esac
cat <<EOF
============================================================
OpenDance Studio Web 服务端已部署(Linux 原生站点,无 Docker)
管理端首页: http://${HOST_HINT}/
API 前缀: http://${HOST_HINT}/api
健康检查: http://${HOST_HINT}/health
契约快照: http://${HOST_HINT}/contracts/
OpenDance Studio Web 服务端已部署(业务服务,无 Docker、不含反向代理)
服务监听: http://${API_HOST}:${API_PORT}/
管理端首页: http://${API_HOST}:${API_PORT}/ (由本服务直接提供)
API 前缀: http://${API_HOST}:${API_PORT}/api
健康检查: http://${API_HOST}:${API_PORT}/health
契约快照: http://${API_HOST}:${API_PORT}/contracts/
对外访问: 由另外的反向代理服务转发到上述地址(见 deploy/proxy/)
数据库: 使用现有实例 ${DB_HOST}:${DB_PORT:-3306}/${DB_NAME}
上传目录: ${STORAGE_DIR}
程序目录: ${APP_DIR}
-93
View File
@@ -1,93 +0,0 @@
# ============================================================
# OpenDance Studio —— nginx 站点配置(Linux 原生部署)
#
# 一个站点同时提供:
# / 管理端静态站点(React 构建产物)
# /api/ NestJS API 反向代理
# /health 健康检查反向代理
# /static/ 上传文件(模型 / 音频 / 关键点),由 API 提供
# /contracts/ 契约快照(只读,方便另两端查阅)
#
# 安装位置:/etc/nginx/sites-available/opendance.conf
# (并软链到 /etc/nginx/sites-enabled/)
# ============================================================
server {
listen 80;
listen [::]:80;
server_name __SERVER_NAME__;
# 上传上限:单个 VRM / FBX 可达 512 MiB,必须与后端 UPLOAD_MAX_BYTES 一致
client_max_body_size 512m;
client_body_timeout 300s;
# 管理端静态站点
root __APP_DIR__/admin;
index index.html;
charset utf-8;
# ---- 管理端 SPA ----
location / {
try_files $uri $uri/ /index.html;
}
# Vite 产物带内容哈希,可长缓存
location /assets/ {
expires 30d;
add_header Cache-Control "public, immutable";
try_files $uri =404;
}
# ---- API 反向代理 ----
location /api/ {
proxy_pass http://__API_HOST__:__API_PORT__;
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 30s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;
proxy_request_buffering off;
}
location = /health {
proxy_pass http://__API_HOST__:__API_PORT__/health;
proxy_http_version 1.1;
proxy_set_header Host $host;
access_log off;
}
# ---- 上传文件 ----
location /static/ {
proxy_pass http://__API_HOST__:__API_PORT__;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
expires 7d;
add_header Cache-Control "public";
}
# ---- 契约快照(只读)----
location /contracts/ {
alias __APP_DIR__/contracts/;
autoindex on;
default_type text/plain;
}
# 隐藏文件一律拒绝
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
gzip on;
gzip_types text/plain text/css application/json application/javascript
application/x-ndjson text/xml application/xml image/svg+xml;
gzip_min_length 1024;
}
+182
View File
@@ -0,0 +1,182 @@
# 反向代理说明(nginx / IIS)
> **职责边界**:本 Web 端**只提供业务服务**(NestJS API + 管理端页面),
> **不部署、不配置反向代理**。反向代理由另外的服务或团队负责,本文档只提供配置说明。
>
> 安装脚本 `deploy/install.sh` 不会安装或修改任何反代软件。
## 一、需要转发的目标
本服务**自带管理端页面**,因此反向代理**只需把请求整体转发**到一个地址:
```
http://<后端地址>:3000
```
不需要在代理层单独托管静态文件,也不需要配置 SPA 回退(服务端已处理)。
一个 `location /`(nginx)或一条全匹配规则(IIS)即可。
| 路径 | 内容 | 说明 |
|---|---|---|
| `/` | 管理端页面 | 由 Node 服务提供;前端路由深链接(如 `/songs`)由服务端回退到 `index.html` |
| `/assets/*` | 前端静态资源 | 带内容哈希,可长缓存 |
| `/api/*` | REST API | 契约见 `contracts/rest-api.yaml` |
| `/health` | 健康检查 | 可用作反代的存活探测,数据库不可用时返回 **503** |
| `/static/*` | 上传文件 | 模型 / 音频 / 关键点序列 |
| `/contracts/*` | 契约快照 | 只读,便于另两端查阅 |
> Windows 客户端与 Android 之间的**关键点 WebSocket 链路不经过本服务**,
> 反代无需配置 WebSocket 转发。
## 二、后端绑定地址怎么选
`deploy/.env` 中的 `HOST`:
| 部署形态 | 建议值 | 说明 |
|---|---|---|
| 反代与后端**同机** | `127.0.0.1` | 后端不直接对外暴露,最安全 |
| 反代与后端**不同机** | `0.0.0.0` | 必须用防火墙把 3000 端口限制为仅反代来源可访问 |
改完执行 `systemctl restart opendance-api`(或对应的 `ctl.sh restart`)生效。
## 三、必须同步调整的两项
1. **上传上限**:本服务默认允许 512 MiB(`UPLOAD_MAX_BYTES`)。
代理层默认值通常远小于此(nginx 1 MB、IIS 约 28.6 MB),不改会导致大模型上传失败。
2. **超时**:上传大文件与下载关键点序列可能较慢,代理的读写超时必须放大。
## 四、nginx 配置
完整样例见 [`nginx.conf.example`](nginx.conf.example)。核心内容:
```nginx
upstream opendance_api {
server 127.0.0.1:3000;
keepalive 16;
}
server {
listen 80;
server_name your.domain.com;
client_max_body_size 512m; # ← 必须放开,否则 VRM/FBX 上传失败
client_body_timeout 300s;
location / {
proxy_pass http://opendance_api;
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 Connection "";
proxy_connect_timeout 30s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;
proxy_request_buffering off; # 大文件直接透传,不在代理落盘
}
}
```
安装位置与重载:
```bash
# Debian / Ubuntu
cp nginx.conf.example /etc/nginx/sites-available/opendance.conf
ln -s /etc/nginx/sites-available/opendance.conf /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx
# RHEL 系
cp nginx.conf.example /etc/nginx/conf.d/opendance.conf
nginx -t && systemctl reload nginx
```
## 五、IIS 配置
IIS 需要先安装两个模块(**默认都没有**):
1. **URL Rewrite** — https://www.iis.net/downloads/microsoft/url-rewrite
2. **Application Request Routing (ARR)** — https://www.iis.net/downloads/microsoft/application-request-routing
装完 ARR 后还需启用代理(否则会报 404.4):
```
IIS 管理器 → 选中服务器节点 → Application Request Routing Cache
→ 右侧 Server Proxy Settings → 勾选 Enable proxy → 应用
```
完整 `web.config` 样例见 [`web.config.example`](web.config.example),放到站点根目录即可:
```xml
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="OpenDanceReverseProxy" stopProcessing="true">
<match url="(.*)" />
<action type="Rewrite" url="http://127.0.0.1:3000/{R:1}" />
</rule>
</rules>
</rewrite>
<security>
<requestFiltering>
<!-- 512 MiB:IIS 默认约 28.6 MB,不改大文件上传必失败 -->
<requestLimits maxAllowedContentLength="536870912" />
</requestFiltering>
</security>
<proxy preserveHostHeader="true" />
<serverRuntime uploadReadAheadSize="536870912" />
</system.webServer>
</configuration>
```
### IIS 容易踩的三个坑
1. **`requestLimits` 与 `serverRuntime` 要一起改**。只改前者,SSL 场景下仍会在
读取请求体时失败(`uploadReadAheadSize` 默认仅 48 KB)。
2. **代理超时改的是服务器级配置**,不是站点级。ARR 默认 120 秒,上传大文件会
中断。在 `applicationHost.config` 的 `<webProxy>` 节点调整:
```xml
<webProxy enabled="true" timeout="00:05:00" />
```
3. **`preserveHostHeader`** 需与 ARR 的 "Preserve host header" 设置一致,
否则后端收到的 Host 会变成 `127.0.0.1:3000`,影响日志与重定向。
## 六、HTTPS 与访问控制(可选)
- **HTTPS 终止在反代**:本服务只监听 HTTP,证书配置在 nginx/IIS 侧即可。
- **访问控制**:本版本**未内置登录认证**,如需公网访问,请在反代层加
Basic Auth、IP 白名单或对接已有 SSO。未加任何防护时请只在内网开放。
## 七、自检清单
配置完成后逐项确认:
```bash
# 1. 后端自身可用(绕过反代)
curl -i http://127.0.0.1:3000/health
# 2. 经反代可访问
curl -i http://<反代地址>/health
# 3. 管理端页面可打开(应返回 HTML)
curl -i http://<反代地址>/ | head -5
# 4. 前端深链接可用(应返回同一份 HTML,而不是 404)
curl -i http://<反代地址>/songs | head -5
# 5. API 可用
curl -i http://<反代地址>/api/catalog/version
# 6. 上传上限已放开:找一个小于 UPLOAD_MAX_BYTES 的文件试传
# 若返回 413 说明代理层限制没改
```
| 现象 | 原因 |
|---|---|
| 反代 502 / 504 | 后端未启动,或 `HOST` 绑定地址不对(同机应为 `127.0.0.1`,异机应为 `0.0.0.0`) |
| 页面能开、接口 404 | 只转发了 `/`,需要把 `/api/`、`/health`、`/static/` 一并转发(最简单是全匹配) |
| 上传大文件 413 | 代理层上传上限没放开(见第三、四、五节) |
| 上传中途断开 | 代理超时太短 |
| `/songs` 直接访问 404 | SPA 回退被代理拦截;本服务已处理,代理**不要**自己加 `try_files`,全匹配转发即可 |
+122
View File
@@ -0,0 +1,122 @@
# ============================================================
# OpenDance Studio Web 服务端 —— nginx 反向代理样例
#
# 说明:本 Web 端不自带反向代理。本文件是**给你的反代服务参考**的配置样例,
# 由部署 `deploy/install.sh` 之外的反代负责人使用。
#
# 特点:后端(NestJS)自带管理端页面与 SPA 回退,因此这里
# 只需一个全匹配 location 把请求整体转发过去即可,
# 不需要 root/try_files 托管静态文件。
#
# 安装:
# Debian/Ubuntu: /etc/nginx/sites-available/opendance.conf(再软链到 sites-enabled/)
# RHEL 系: /etc/nginx/conf.d/opendance.conf
# 校验并重载: nginx -t && systemctl reload nginx
# ============================================================
upstream opendance_api {
# 后端地址:同机用 127.0.0.1;异机改成实际 IP,并在后端放防火墙
server 127.0.0.1:3000;
keepalive 16;
}
server {
listen 80;
listen [::]:80;
server_name your.domain.com; # 改成实际域名或 _
# 字符集:管理端与 API 都是 UTF-8
charset utf-8;
# ★ 上传上限:后端默认允许 512 MiB,nginx 默认仅 1 MB,
# 不改会导致 VRM / FBX 等大文件上传直接 413。
client_max_body_size 512m;
client_body_timeout 300s;
access_log /var/log/nginx/opendance.access.log;
error_log /var/log/nginx/opendance.error.log;
# ---- 全部请求转发给后端 ----
# 管理端页面、前端路由深链接、/api、/health、/static、/contracts
# 全部由后端处理,所以这里只需一条规则。
location / {
proxy_pass http://opendance_api;
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;
# 配合 upstream keepalive,避免 Connection: close
proxy_set_header Connection "";
# ★ 超时:大文件上传与关键点序列下载都可能较慢
proxy_connect_timeout 30s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;
# 大文件直接透传,不在代理层落盘
proxy_request_buffering off;
proxy_buffering off;
}
# 健康检查可单独放开日志噪音(可选)
location = /health {
proxy_pass http://opendance_api/health;
proxy_http_version 1.1;
proxy_set_header Host $host;
access_log off;
}
gzip on;
gzip_types text/plain text/css application/json application/javascript
application/x-ndjson text/xml application/xml image/svg+xml;
gzip_min_length 1024;
# 若前端资源由后端返回,代理层不要缓存 HTML,避免升级后页面不更新
location ~* \.html$ {
proxy_pass http://opendance_api;
proxy_http_version 1.1;
proxy_set_header Host $host;
add_header Cache-Control "no-cache";
}
}
# ============================================================
# 可选:HTTPS 终止在反代(后端只监听 HTTP)
#
# server {
# listen 443 ssl;
# http2 on;
# server_name your.domain.com;
#
# ssl_certificate /etc/nginx/ssl/opendance.crt;
# ssl_certificate_key /etc/nginx/ssl/opendance.key;
# ssl_protocols TLSv1.2 TLSv1.3;
#
# client_max_body_size 512m;
#
# location / {
# proxy_pass http://opendance_api;
# 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_send_timeout 300s;
# proxy_read_timeout 300s;
# proxy_request_buffering off;
# }
# }
# ============================================================
# ============================================================
# 可选:本服务未内置登录认证,如需公网访问请在反代加一层防护
#
# location / {
# auth_basic "OpenDance Studio";
# auth_basic_user_file /etc/nginx/.htpasswd; # htpasswd -c 生成
# proxy_pass http://opendance_api;
# ...
# }
# ============================================================
+85
View File
@@ -0,0 +1,85 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
============================================================
OpenDance Studio Web 服务端 —— IIS 反向代理样例
说明:本 Web 端不自带反向代理。本文件是**给你的反代服务参考**的配置样例。
前置条件(IIS 默认都不带,需自行安装):
1. URL Rewrite 模块
https://www.iis.net/downloads/microsoft/url-rewrite
2. Application Request Routing (ARR)
https://www.iis.net/downloads/microsoft/application-request-routing
3. 启用 ARR 代理(否则会 404.4):
IIS 管理器 → 服务器节点 → Application Request Routing Cache
→ Server Proxy Settings → 勾选 Enable proxy
放置位置:IIS 站点根目录下的 web.config
后端(NestJS)自带管理端页面与 SPA 回退,所以这里只需一条全匹配重写规则,
不需要在 IIS 上再配置默认文档或 URL Rewrite 的 SPA 回退。
============================================================
-->
<configuration>
<system.webServer>
<rewrite>
<rules>
<!-- 全部请求转发给后端:管理端页面 / 前端深链接 / api / health / static / contracts -->
<rule name="OpenDanceReverseProxy" stopProcessing="true">
<match url="(.*)" />
<action type="Rewrite" url="http://127.0.0.1:3000/{R:1}" />
</rule>
</rules>
<!-- 若需要 HTTPS 终止,取消下面一段注释(IIS 侧装证书) -->
<!--
<outboundRules>
<rule name="RewriteRedirectToHttps" preCondition="IsRedirect">
<match serverVariable="RESPONSE_Location" pattern="^http://(.*)" />
<action type="Rewrite" value="https://{R:1}" />
</rule>
<preConditions>
<preCondition name="IsRedirect">
<add input="{RESPONSE_STATUS}" pattern="3\d\d" />
</preCondition>
</preConditions>
</outboundRules>
-->
</rewrite>
<security>
<requestFiltering>
<!-- ★ 上传上限 512 MiB。IIS 默认约 28.6 MB,不改大文件上传必失败(413) -->
<requestLimits maxAllowedContentLength="536870912" />
</requestFiltering>
</security>
<!-- ★ 与上一条配合:SSL 场景下请求体预读缓冲,默认仅 48 KB,不改仍会失败 -->
<serverRuntime uploadReadAheadSize="536870912" />
<!-- 保留原始 Host 头,后端日志与重定向才正确 -->
<proxy preserveHostHeader="true" />
<httpProtocol>
<customHeaders>
<remove name="X-Powered-By" />
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>
<!--
┌──────────────────────────────────────────────────────────────┐
│ 两个最常踩的坑 │
├──────────────────────────────────────────────────────────────┤
│ 1. 代理超时是**服务器级**配置,不在 web.config 里。 │
│ ARR 默认 120 秒,上传大模型会中途断开。改 │
│ C:\Windows\System32\inetsrv\config\applicationHost.config │
│ 的 <webProxy> 节点: │
│ <webProxy enabled="true" timeout="00:05:00" /> │
│ 改完 iisreset 或重启 W3SVC。 │
│ │
│ 2. requestLimits 与 serverRuntime 必须**同时**改。 │
│ 只改前者,HTTPS 下仍会因 uploadReadAheadSize 太小而失败。 │
└──────────────────────────────────────────────────────────────┘
-->