- Podstawy WebSocket i ich działanie w środowisku hostingu
- Czym jest WebSocket z perspektywy serwera
- Dlaczego używa się Nginx jako reverse proxy dla WebSocket
- Ograniczenia typowych środowisk hostingowych
- Jak wygląda typowy przebieg połączenia WebSocket przez Nginx
- Przygotowanie środowiska hostingowego pod WebSockety
- Wymagania względem hostingu
- Dobór aplikacji serwerowej i portu nasłuchu
- Struktura katalogów i plików konfiguracyjnych na hostingu
- Aspekty bezpieczeństwa i SSL przed wdrożeniem
- Konfiguracja Nginx dla WebSocketów krok po kroku
- Podstawowy blok server i dopasowanie lokalizacji
- Niezbędne nagłówki i dyrektywy dla połączeń WebSocket
- Timeouty, buforowanie i limity połączeń
- Obsługa SSL (HTTPS/WSS) dla WebSocketów
- Przykłady konfiguracji dla różnych scenariuszy hostingu
- Konfiguracja na VPS z pełnym dostępem do Nginx
- Konfiguracja na hostingu współdzielonym z panelem
- Osobna subdomena tylko dla WebSocket
- Łączenie aplikacji HTTP API i WebSocket pod jednym hostem
Konfiguracja WebSocketów za pośrednictwem Nginx to częsty problem osób korzystających z współdzielonego lub VPS-owego hostingu. Sam protokół wydaje się prosty, ale po drodze pojawiają się kwestie SSL, nagłówków, time‑outów, a także ograniczeń narzuconych przez panel hostingowy. Ten poradnik pokazuje krok po kroku, jak poprawnie skonfigurować Nginx jako odwrotny proxy dla aplikacji WebSocket, zwracając szczególną uwagę na realne scenariusze hostingowe i typowe pułapki.
Podstawy WebSocket i ich działanie w środowisku hostingu
Czym jest WebSocket z perspektywy serwera
Protokół WebSocket pozwala na utrzymywanie trwałego, dwukierunkowego połączenia między przeglądarką a serwerem. W przeciwieństwie do klasycznego HTTP, gdzie każda odpowiedź kończy żądanie, WebSocket tworzy kanał komunikacyjny, który może działać godzinami. Dla serwera oznacza to inne wzorce obciążenia: zamiast wielu krótkich żądań mamy mniejszą liczbę długotrwałych połączeń. W środowisku hostingu ma to duży wpływ na limity zasobów, konfigurację time‑outów i sposób skalowania aplikacji.
Samo połączenie WebSocket zaczyna się zawsze od zapytania HTTP/HTTPS typu upgrade. Klient wysyła nagłówki prosząc o przejście z protokołu HTTP na WebSocket, a serwer – jeśli aplikacja jest do tego przygotowana – akceptuje przełączenie. W tym momencie rola klasycznego serwera HTTP (np. Nginx) często ogranicza się do pośredniczenia w ruchu, czyli działania jako tzw. reverse proxy, przekazującego dane do procesu aplikacji nasłuchującego na innym porcie.
Dlaczego używa się Nginx jako reverse proxy dla WebSocket
Na hostingu, szczególnie współdzielonym, rzadko mamy bezpośredni dostęp do portów i serwerów frontowych. Dostawca dostarcza skonfigurowany stos WWW, w którym Nginx pełni rolę serwera wejściowego. Zamiast wystawiać aplikację WebSocket bezpośrednio, uruchamiamy ją na lokalnym porcie (np. 3000, 8080), a Nginx przekierowuje ruch spod publicznego adresu. Pozwala to m.in. na:
- terminację SSL na Nginx – certyfikat jest obsługiwany w jednym miejscu, aplikacja może działać na HTTP;
- ukrycie wewnętrznej architektury, portów i usług przed światem zewnętrznym;
- równoważenie obciążenia między wieloma instancjami aplikacji;
- stosowanie reguł bezpieczeństwa (rate limiting, firewall aplikacyjny, nagłówki bezpieczeństwa).
Konfiguracja WebSocketów wymaga jednak od Nginx obsługi połączeń utrzymywanych przez dłuższy czas oraz poprawnej obsługi nagłówków upgrade i connection. Bez tego połączenia będą niespodziewanie zrywane, a przeglądarka wyświetli błędy lub spróbuje nieskończonego ponawiania połączeń.
Ograniczenia typowych środowisk hostingowych
Wybierając hosting, warto rozróżnić trzy podstawowe typy środowisk, bo od tego zależy, ile naprawdę możemy skonfigurować:
- hosting współdzielony – ograniczony dostęp, często brak możliwości edycji głównej konfiguracji Nginx; do dyspozycji są pliki użytkownika (np. fragmenty configu) lub interfejs w panelu;
- VPS / serwer dedykowany – pełna kontrola nad konfiguracją, możliwość instalacji własnej wersji Nginx, systemd, firewalli i narzędzi monitoringu;
- managed hosting aplikacyjny (np. PaaS) – konfiguracja jest często oparta na gotowych szablonach, a WebSocket wymaga jedynie włączenia odpowiedniej opcji w panelu.
W praktyce konfiguracja WebSocketów najwięcej trudności sprawia na hostingu współdzielonym, gdzie nie mamy bezpośredniego dostępu do głównego pliku nginx.conf. Nawet wtedy da się jednak poprawnie skonfigurować proxy – o ile dostawca pozwala na użycie sekcji location i ustawienie podstawowych nagłówków proxy.
Jak wygląda typowy przebieg połączenia WebSocket przez Nginx
Typowe zapytanie WebSocket przechodzi przez kilka etapów:
- Przeglądarka nawiązuje połączenie do URL w formacie ws://domena.pl/socket lub wss://domena.pl/socket.
- Nginx odbiera połączenie na porcie 80 lub 443 i rozpoznaje je na podstawie dopasowanego location.
- Nginx sprawdza nagłówki Upgrade i Connection, a następnie przekazuje połączenie dalej do aplikacji nasłuchującej na wewnętrznym porcie.
- Aplikacja zaakceptuje lub odrzuci handshake. Jeżeli wszystko jest poprawnie skonfigurowane, połączenie pozostaje otwarte, a dane płyną w obie strony aż do zamknięcia sesji.
W dalszej części przejdziemy do przygotowania środowiska hostingowego i konkretnych plików konfiguracyjnych, tak aby ten przepływ działał stabilnie i bez zbędnych przerw.
Przygotowanie środowiska hostingowego pod WebSockety
Wymagania względem hostingu
Zanim zaczniemy wprowadzać zmiany w konfiguracji, trzeba zweryfikować, czy nasz dostawca hostingu w ogóle wspiera protokół WebSocket. Niektórzy operatorzy w planach współdzielonych blokują długotrwałe połączenia, ograniczając czas życia gniazd lub liczbę jednoczesnych procesów. Jeśli w dokumentacji widnieje informacja o braku wsparcia dla aplikacji typu real‑time, lepszym wyborem będzie VPS.
Minimalne wymagania, na jakie warto zwrócić uwagę:
- możliwość utrzymania połączenia przez co najmniej kilkadziesiąt minut bez wymuszonych resetów;
- dostęp do konfiguracji Nginx w formie plików include lub panelu umożliwiającego edycję reguł;
- możliwość uruchamiania stałych procesów aplikacyjnych (Node.js, Python, PHP-FPM z long‑running workerami, serwery Go, itp.);
- brak twardych limitów na liczbę połączeń TCP, które dyskwalifikowałyby aplikacje z większym ruchem.
Jeżeli hosting oferuje jedynie dostęp do panelu WWW i nie pozwala na uruchomienie własnego procesu nasłuchującego na porcie, można rozważyć przeniesienie części systemu w miejsce, gdzie WebSocket będzie mógł działać (np. osobny VPS) i użycie domeny lub subdomeny tylko dla modułu real‑time.
Dobór aplikacji serwerowej i portu nasłuchu
Nginx nie implementuje logiki WebSocket po stronie aplikacyjnej – jego zadaniem jest głównie pośredniczenie. Logika czatu, powiadomień, transmisji danych w czasie rzeczywistym działa w dedykowanym procesie. Najczęściej jest to:
- aplikacja Node.js z biblioteką ws, Socket.IO lub NestJS WebSockets;
- serwer w Pythonie (np. Django Channels, FastAPI z uvicorn, websockets);
- aplikacja w Go korzystająca z bibliotek WebSocket;
- frameworki JVM, np. Spring Boot z obsługą STOMP/WebSocket.
Aplikację uruchamiamy zwykle na porcie wewnętrznym, np. 3000, 4000, 8080. Ten port nie jest bezpośrednio dostępny z Internetu – jest chroniony przez Nginx, który wystawia go na zewnątrz pod konkretnym adresem URL. Taki model jest zgodny z polityką większości hostingów: tylko Nginx jest widoczny z zewnątrz, aplikacje za nim pozostają w sieci prywatnej lub w obrębie kontenera.
Struktura katalogów i plików konfiguracyjnych na hostingu
Na VPS zazwyczaj mamy dostęp do katalogów typu:
- /etc/nginx/nginx.conf – główny plik konfiguracji;
- /etc/nginx/sites-available/ oraz /etc/nginx/sites-enabled/ – definicje serwerów wirtualnych;
- /var/www/domena – katalog z plikami aplikacji.
Na hostingu współdzielonym struktura może być uproszczona. Dostawca udostępnia fragmenty w rodzaju:
- ~/conf/nginx/domains/domena.conf;
- panel do edycji sekcji server / location;
- pole na „dodatkowe dyrektywy Nginx” w konfiguracji domeny.
Ważne, by wiedzieć, gdzie można wstawić swoją sekcję location /socket oraz jak podpiąć ją pod istniejący blok server, który obsługuje naszą domenę. W kolejnych przykładach przyjmijmy, że możemy edytować lub uzupełniać konfigurację w jednym z takich plików i że mamy dostęp do restartu lub przeładowania usługi Nginx.
Aspekty bezpieczeństwa i SSL przed wdrożeniem
Już na etapie przygotowania trzeba zdecydować, czy nasz WebSocket będzie działał w wariancie ws:// czy wss://. W praktyce, jeśli nasze API HTTP korzysta z HTTPS, również WebSocket powinien działać jako wss. Przeglądarki nie pozwalają na mieszanie treści bezpiecznych i niebezpiecznych w wielu kontekstach, więc ws:// przy stronie serwowanej po HTTPS zwykle prowadzi do błędów.
Jeśli hosting oferuje darmowy certyfikat Let’s Encrypt, najlepiej zakończyć połączenie SSL na Nginx i przekazywać ruch do aplikacji po HTTP. Aplikacja sama nie musi wiedzieć, że połączenie było szyfrowane – komunikacja wewnątrz serwera lub kontenera i tak odbywa się w bezpieczniejszym środowisku. Wymaga to jednak poprawnego skonfigurowania serwera na porcie 443 i ustawienia odpowiednich nagłówków proxy do aplikacji WebSocket.
Konfiguracja Nginx dla WebSocketów krok po kroku
Podstawowy blok server i dopasowanie lokalizacji
Punktem wyjścia jest blok server, który obsługuje naszą domenę. Załóżmy, że w wersji najprostszej wygląda on następująco (roboczy przykład, w praktyce dostosuj go do swojego hostingu):
server {
listen 80;
server_name moja-domena.pl;
root /var/www/moja-domena.pl/public;
}
Żeby skierować żądania pod konkretną ścieżkę, np. /ws, do backendu WebSocket, dodajemy sekcję location w tym samym bloku server. Ważne, by dopasowanie było na tyle specyficzne, aby nie kolidowało z ruchem HTTP. Jeśli aplikacja WebSocket używa osobnej subdomeny (np. ws.moja‑domena.pl), najlepiej stworzyć osobny blok server, co ułatwia zarządzanie konfiguracją.
Niezbędne nagłówki i dyrektywy dla połączeń WebSocket
Kluczową częścią konfiguracji WebSocketów jest zachowanie nagłówków Upgrade i Connection oraz przełączenie Nginx w tryb proxy_http_version 1.1. Przykładowa konfiguracja lokalizacji może wyglądać tak:
location /ws {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection „upgrade”;
proxy_set_header Host $host;
}
Istotne elementy:
- proxy_http_version 1.1 – WebSocket wymaga HTTP/1.1, starsza wersja 1.0 nie obsługuje mechanizmu upgrade;
- proxy_set_header Upgrade – przekazuje oryginalną wartość nagłówka Upgrade, dzięki czemu backend rozpoznaje handshake;
- proxy_set_header Connection „upgrade” – wymusza zachowanie połączenia zgodnie z wymaganiami WebSocket;
- proxy_set_header Host – pomaga aplikacji rozpoznać poprawną domenę, co jest istotne m.in. przy generowaniu linków, logowaniu czy CORS.
Bez tych nagłówków przeglądarka może nie dostać poprawnej odpowiedzi 101 Switching Protocols, a połączenie WebSocket będzie natychmiast kończone lub nawet w ogóle nie zostanie nawiązane.
Timeouty, buforowanie i limity połączeń
Standardowa konfiguracja Nginx jest optymalizowana pod krótkie żądania HTTP. W przypadku WebSocketów musimy świadomie dobrać parametry takie jak:
- proxy_read_timeout – maksymalny czas oczekiwania na dane z backendu;
- proxy_send_timeout – maksymalny czas oczekiwania na wysłanie danych do backendu;
- proxy_buffering – czy odpowiedzi mają być buforowane (dla WebSocketów zwykle wyłączamy).
Przykładowa rozszerzona konfiguracja może wyglądać tak:
location /ws {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection „upgrade”;
proxy_set_header Host $host;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
proxy_buffering off;
}
Wartości 3600 sekund (1 godzina) są często wystarczające w aplikacjach, gdzie użytkownik pozostaje zalogowany przez dłuższy czas. Niektóre hostingi nadpisują jednak te ustawienia globalnymi limitami, co może prowadzić do zerwania połączeń po określonym czasie mimo poprawnej konfiguracji w pliku domeny. W takiej sytuacji pozostaje kontakt z supportem lub przeniesienie krytycznych komponentów na infrastrukturę z pełną kontrolą nad Nginx.
Obsługa SSL (HTTPS/WSS) dla WebSocketów
Jeżeli domena korzysta z HTTPS, WebSocket powinien działać jako wss. W konfiguracji Nginx oznacza to dodanie bloku server dla portu 443, np.:
server {
listen 443 ssl;
server_name moja-domena.pl;
ssl_certificate /etc/letsencrypt/live/moja-domena.pl/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/moja-domena.pl/privkey.pem;
location /ws {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection „upgrade”;
proxy_set_header Host $host;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
proxy_buffering off;
}
}
Przy takim ustawieniu przeglądarka łączy się z Nginx po protokole TLS, a Nginx deszyfruje ruch i przekazuje go dalej jako nieszyfrowany HTTP. Dla aplikacji cały proces jest przeźroczysty – WebSocket jest po prostu kolejnym połączeniem na porcie 3000. Jeśli hosting zarządza certyfikatami automatycznie, część dyrektyw ssl_ może być już skonfigurowana globalnie, a my dodajemy tylko sekcję location.
Przykłady konfiguracji dla różnych scenariuszy hostingu
Konfiguracja na VPS z pełnym dostępem do Nginx
Na VPS-ie mamy najbardziej elastyczne środowisko, dlatego całość konfiguracji możemy uporządkować zgodnie z najlepszymi praktykami. Załóżmy, że mamy plik /etc/nginx/sites-available/moja-domena.pl połączony z katalogiem sites-enabled. Przykładowa konfiguracja może wyglądać tak:
server {
listen 80;
server_name moja-domena.pl;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name moja-domena.pl;
ssl_certificate /etc/letsencrypt/live/moja-domena.pl/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/moja-domena.pl/privkey.pem;
root /var/www/moja-domena.pl/public;
index index.html index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location /ws {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection „upgrade”;
proxy_set_header Host $host;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
proxy_buffering off;
}
}
Po wprowadzeniu tej konfiguracji wykonujemy test syntaktyczny komendą nginx -t, a następnie przeładowujemy usługę (na przykład systemctl reload nginx). Jeśli test przejdzie pomyślnie, nasz WebSocket będzie dostępny pod adresem wss://moja-domena.pl/ws. W aplikacji frontendowej wystarczy teraz użyć adresu w formie new WebSocket(’wss://moja-domena.pl/ws’).
Konfiguracja na hostingu współdzielonym z panelem
W przypadku hostingu współdzielonego dostawca często udostępnia możliwość wprowadzenia dodatkowych dyrektyw Nginx dla konkretnej domeny. W praktyce widzimy w panelu edytor pozwalający na wpisanie fragmentu konfiguracji w sekcji server. W takim wypadku wklejamy jedynie sekcję location, zakładając, że reszta (listen, ssl, server_name) jest już skonfigurowana przez dostawcę:
location /ws {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection „upgrade”;
proxy_set_header Host $host;
proxy_read_timeout 1800s;
proxy_send_timeout 1800s;
proxy_buffering off;
}
Port 3000 powinien być dostępny w obrębie konta, np. w ramach kontenera lub wewnętrznej sieci hostingu. Aplikację WebSocket uruchamiamy w tle, korzystając np. z menedżera procesów (PM2 dla Node.js, supervisord dla Pythona) lub systemowego mechanizmu oferowanego przez panel. Kluczowe jest też sprawdzenie dokumentacji hostingu, czy długotrwałe procesy nie są automatycznie zabijane po kilku minutach bezczynności.
Osobna subdomena tylko dla WebSocket
Często wygodniej jest wydzielić WebSocket na osobną subdomenę, np. ws.moja-domena.pl. Pozwala to:
- izolować konfigurację Nginx dla samej usługi real‑time;
- stosować osobne limity i logi dla ruchu WebSocket;
- korzystać z innego backendu (inna aplikacja, inny serwer).
Konfiguracja na VPS mogłaby wyglądać następująco:
server {
listen 443 ssl;
server_name ws.moja-domena.pl;
ssl_certificate /etc/letsencrypt/live/ws.moja-domena.pl/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/ws.moja-domena.pl/privkey.pem;
location / {
proxy_pass http://127.0.0.1:4000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection „upgrade”;
proxy_set_header Host $host;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
proxy_buffering off;
}
}
Tutaj cała subdomena jest przeznaczona dla WebSocketów, więc location / pełni rolę głównego endpointu. Aplikacja może obsługiwać różne ścieżki kanałów czatu czy powiadomień już wewnątrz protokołu WebSocket, bez dodatkowego rozgałęziania po stronie Nginx.
Łączenie aplikacji HTTP API i WebSocket pod jednym hostem
W wielu projektach chcemy połączyć klasyczne REST API oraz WebSockety pod jedną domeną i certyfikatem. Nginx świetnie się do tego nadaje, ponieważ możemy skonfigurować różne ścieżki kierowane do różnych backendów. Przykładowa konfiguracja:
server {
listen 443 ssl;
server_name api.moja-domena.pl;
ssl_certificate /etc/letsencrypt/live/api.moja-domena.pl/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/api.moja-domena.pl/privkey.pem;
location /v1/ {
proxy_pass http://127.0.0.1:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /ws {
proxy_pass http://127.0.0.1:6000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection „upgrade”;
proxy_set_header Host $host;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
proxy_buffering off;
}
}
Takie rozwiązanie pozwala na niezależne skalowanie backendu REST i backendu WebSocket. Na hostingu współdzielonym warto jednak zwrócić uwagę na limity procesów i pamięci – dwie osobne aplikacje to podwójne zużycie zasobów, co może wymagać wyższego planu lub przejścia na VPS.