反向代理
如果你在 Nginx、Nginx Proxy Manager、Caddy、Cloudflare 或其他反向代理后运行 OpenChamber,请使用本页。
在代理之前
- 先确认 OpenChamber 可以直接工作。
- 从同一网络打开
http://<server-ip>:3000或你的自定义端口。 - 只有在直接连接可用之后,才添加反向代理。
代理必须支持的内容
- 用于实时消息传输的 WebSocket:
/api/event/ws/api/global/event/ws/api/terminal/ws
- 不带缓冲的 SSE:
/api/event/api/global/event/api/notifications/stream/api/openchamber/events/api/terminal/:sessionId/stream
- 用于附件和文件操作的大请求体
- 用于实时流和终端会话的长读取超时
重要规则
- 启用 WebSocket 代理。
- 在 SSE 路由上禁用缓冲。
- 如果 OpenChamber 已经压缩响应,请在代理上禁用 gzip。
- 仅在一层中保持压缩开启。
- 转发常规代理标头,例如
Host、X-Forwarded-For和X-Forwarded-Proto。 - 如果用户上传文件,请增大请求体大小限制。
快速检查清单
- OpenChamber 可在 LAN 内直接访问
- 代理中已启用 WebSocket
- SSE 路由已关闭缓冲
- 代理主机上
gzip off,或以其他方式禁用代理压缩 client_max_body_size足够大以容纳附件proxy_read_timeout足够长以容纳流
示例:Nginx
显示示例配置
client_max_body_size 50M;client_body_buffer_size 50M;proxy_request_buffering off;
proxy_http_version 1.1;proxy_set_header Connection "";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 X-Forwarded-Host $host;
gzip off;
location = /api/terminal/ws { proxy_pass http://127.0.0.1:3000; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_buffering off; proxy_cache off; proxy_read_timeout 3600s; proxy_send_timeout 3600s;}
location = /api/global/event/ws { proxy_pass http://127.0.0.1:3000; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_buffering off; proxy_cache off; proxy_read_timeout 3600s; proxy_send_timeout 3600s;}
location = /api/event/ws { proxy_pass http://127.0.0.1:3000; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_buffering off; proxy_cache off; proxy_read_timeout 3600s; proxy_send_timeout 3600s;}
location ~ ^/api/(event|global/event|notifications/stream|openchamber/events)$ { proxy_pass http://127.0.0.1:3000; proxy_set_header Accept "text/event-stream"; proxy_set_header Cache-Control "no-cache"; proxy_buffering off; proxy_cache off; gzip off; add_header X-Accel-Buffering "no" always; add_header Cache-Control "no-cache, no-transform" always; proxy_read_timeout 3600s; proxy_send_timeout 3600s;}
location ~ ^/api/terminal/.+/stream$ { proxy_pass http://127.0.0.1:3000; proxy_set_header Accept "text/event-stream"; proxy_set_header Cache-Control "no-cache"; proxy_buffering off; proxy_cache off; gzip off; add_header X-Accel-Buffering "no" always; add_header Cache-Control "no-cache, no-transform" always; proxy_read_timeout 3600s; proxy_send_timeout 3600s;}
location /api { proxy_pass http://127.0.0.1:3000; proxy_read_timeout 3600s; proxy_send_timeout 3600s;}
location / { proxy_pass http://127.0.0.1:3000;}示例:Nginx Proxy Manager
显示 Advanced 选项卡示例
client_max_body_size 50M;client_body_buffer_size 50M;proxy_request_buffering off;
proxy_http_version 1.1;proxy_set_header Connection "";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 X-Forwarded-Host $host;
gzip off;
location = /api/terminal/ws { proxy_pass http://127.0.0.1:3000; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_buffering off; proxy_cache off; proxy_read_timeout 3600s; proxy_send_timeout 3600s; proxy_connect_timeout 30s;}
location = /api/global/event/ws { proxy_pass http://127.0.0.1:3000; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_buffering off; proxy_cache off; proxy_read_timeout 3600s; proxy_send_timeout 3600s; proxy_connect_timeout 30s;}
location = /api/event/ws { proxy_pass http://127.0.0.1:3000; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_buffering off; proxy_cache off; proxy_read_timeout 3600s; proxy_send_timeout 3600s; proxy_connect_timeout 30s;}
location = /api/event { proxy_pass http://127.0.0.1:3000; proxy_set_header Accept "text/event-stream"; proxy_set_header Cache-Control "no-cache"; proxy_buffering off; proxy_cache off; gzip off; add_header X-Accel-Buffering "no" always; add_header Cache-Control "no-cache, no-transform" always; proxy_read_timeout 3600s; proxy_send_timeout 3600s; proxy_connect_timeout 30s;}
location = /api/global/event { proxy_pass http://127.0.0.1:3000; proxy_set_header Accept "text/event-stream"; proxy_set_header Cache-Control "no-cache"; proxy_buffering off; proxy_cache off; gzip off; add_header X-Accel-Buffering "no" always; add_header Cache-Control "no-cache, no-transform" always; proxy_read_timeout 3600s; proxy_send_timeout 3600s; proxy_connect_timeout 30s;}
location = /api/notifications/stream { proxy_pass http://127.0.0.1:3000; proxy_set_header Accept "text/event-stream"; proxy_set_header Cache-Control "no-cache"; proxy_buffering off; proxy_cache off; gzip off; add_header X-Accel-Buffering "no" always; add_header Cache-Control "no-cache, no-transform" always; proxy_read_timeout 3600s; proxy_send_timeout 3600s; proxy_connect_timeout 30s;}
location = /api/openchamber/events { proxy_pass http://127.0.0.1:3000; proxy_set_header Accept "text/event-stream"; proxy_set_header Cache-Control "no-cache"; proxy_buffering off; proxy_cache off; gzip off; add_header X-Accel-Buffering "no" always; add_header Cache-Control "no-cache, no-transform" always; proxy_read_timeout 3600s; proxy_send_timeout 3600s; proxy_connect_timeout 30s;}
location ~ ^/api/terminal/.+/stream$ { proxy_pass http://127.0.0.1:3000; proxy_set_header Accept "text/event-stream"; proxy_set_header Cache-Control "no-cache"; proxy_buffering off; proxy_cache off; gzip off; add_header X-Accel-Buffering "no" always; add_header Cache-Control "no-cache, no-transform" always; proxy_read_timeout 3600s; proxy_send_timeout 3600s; proxy_connect_timeout 30s;}
location /api { proxy_pass http://127.0.0.1:3000; proxy_read_timeout 3600s; proxy_send_timeout 3600s; proxy_connect_timeout 30s;}
location / { proxy_pass http://127.0.0.1:3000;}另外,请在 Nginx Proxy Manager 中为此主机启用 Websockets Support。
常见故障迹象
页面能加载,但发送消息失败
- 代理中未启用 WebSocket
/api/event/ws或/api/global/event/ws未正确传递
通知或实时状态不更新
- 某个 SSE 路由被缓冲或缓存
- 缺少
X-Accel-Buffering "no"
文件上传失败
client_max_body_size太小
本地一切正常,但仅在代理后出问题
- 代理正在压缩和缓冲实时流量
- 代理缺少 WebSocket 支持
示例:Caddy
显示示例配置
reverse_proxy 127.0.0.1:3000 { # WebSocket support is automatic in Caddy
# Flush SSE responses immediately flush_interval -1
# Pass through Host and proxy headers header_up Host {host} header_up X-Real-IP {remote_host} header_up X-Forwarded-For {remote_host} header_up X-Forwarded-Proto {scheme}
# Increase timeouts for long-lived streams transport http { read_timeout 3600s write_timeout 3600s }}Caddy 会自动处理 WebSocket 升级 — 无需额外配置。flush_interval -1 指令可确保 SSE 数据块立即转发,不带缓冲。
CDN 与双重压缩警告
如果你在反向代理前面放置 CDN(例如 Cloudflare),请注意双重压缩:
- OpenChamber 使用 gzip 压缩 HTTP 响应(阈值 1 KB)。
- Cloudflare 和其他 CDN 默认也会压缩响应。
- 这可能导致响应被双重压缩或
Content-Encoding标头不正确。
为避免这种情况,请在一层中禁用压缩:
- Cloudflare: Rules → Compression → disable(或使用 “Passthrough” 模式)。
- Nginx:
gzip off(上面的示例已展示)。 - Caddy: 如果上游已发送压缩内容,Caddy 默认不会重新压缩。
SSE 流式路由已被 OpenChamber 排除在压缩之外,但 CDN 仍可能缓冲它们。请查阅你的 CDN 文档,了解如何在 SSE 路径上禁用缓冲。