Reverse proxy
Skorzystaj z tej strony, jeśli uruchamiasz OpenChamber za Nginx, Nginx Proxy Manager, Caddy, Cloudflare lub innym reverse proxy.
Zanim ustawisz proxy
- Najpierw potwierdź, że OpenChamber działa bezpośrednio.
- Otwórz
http://<server-ip>:3000lub swój własny port z tej samej sieci. - Dodaj reverse proxy dopiero, gdy połączenie bezpośrednie działa.
Co proxy musi obsługiwać
- WebSockets do transportu wiadomości na żywo:
/api/event/ws/api/global/event/ws/api/terminal/ws
- SSE bez buforowania:
/api/event/api/global/event/api/notifications/stream/api/openchamber/events/api/terminal/:sessionId/stream
- Duże treści żądań dla załączników i operacji na plikach
- Długie limity czasu odczytu dla strumieni na żywo i sesji terminala
Reguły, które mają znaczenie
- Włącz proxy WebSocket.
- Wyłącz buforowanie na trasach SSE.
- Wyłącz gzip na proxy, jeśli OpenChamber już kompresuje odpowiedzi.
- Utrzymuj kompresję włączoną tylko w jednej warstwie.
- Przekazuj zwykłe nagłówki proxy, takie jak
Host,X-Forwarded-ForiX-Forwarded-Proto. - Zwiększ limity rozmiaru treści, jeśli użytkownicy przesyłają pliki.
Szybka lista kontrolna
- OpenChamber dostępny bezpośrednio w LAN
- WebSockets włączone w proxy
- trasy SSE mają wyłączone buforowanie
gzip offna hoście proxy lub kompresja proxy wyłączona w inny sposóbclient_max_body_sizewystarczająco duży dla załącznikówproxy_read_timeoutwystarczająco długi dla strumieni
Przykład: Nginx
Pokaż przykładową konfigurację
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;}Przykład: Nginx Proxy Manager
Pokaż przykład z karty 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;}Włącz także Websockets Support w Nginx Proxy Manager dla tego hosta.
Typowe oznaki awarii
Strona się ładuje, ale wysyłanie wiadomości zawodzi
- WebSockets nie są włączone w proxy
/api/event/wslub/api/global/event/wsnie przechodzi poprawnie
Powiadomienia lub status na żywo nie aktualizują się
- jedna z tras SSE jest buforowana lub w pamięci podręcznej
- brakuje
X-Accel-Buffering "no"
Przesyłanie plików zawodzi
client_max_body_sizejest zbyt mały
Wszystko działa lokalnie, ale psuje się tylko za proxy
- proxy kompresuje i buforuje ruch na żywo
- proxy nie obsługuje WebSockets
Przykład: Caddy
Pokaż przykładową konfigurację
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 obsługuje uaktualnienia WebSocket automatycznie — żadna dodatkowa konfiguracja nie jest potrzebna. Dyrektywa flush_interval -1 zapewnia, że fragmenty SSE są przekazywane natychmiast, bez buforowania.
Ostrzeżenie o CDN i podwójnej kompresji
Jeśli umieścisz CDN (np. Cloudflare) przed swoim reverse proxy, pamiętaj o podwójnej kompresji:
- OpenChamber kompresuje odpowiedzi HTTP za pomocą gzip (próg 1 KB).
- Cloudflare i inne CDN-y również domyślnie kompresują odpowiedzi.
- Może to powodować podwójnie skompresowane odpowiedzi lub nieprawidłowe nagłówki
Content-Encoding.
Aby tego uniknąć, wyłącz kompresję w jednej warstwie:
- Cloudflare: Rules → Compression → disable (lub użyj trybu “Passthrough”).
- Nginx:
gzip off(już pokazane w przykładach powyżej). - Caddy: Caddy domyślnie nie kompresuje ponownie, jeśli upstream już wysyła skompresowaną treść.
Trasy strumieniowania SSE są wyłączone z kompresji przez OpenChamber, ale CDN może je nadal buforować. Sprawdź dokumentację swojego CDN, jak wyłączyć buforowanie na ścieżkach SSE.