Как настроить reverse proxy для WebSocket в Nginx

9 минут чтения
Средний рейтинг статьи — 4.7

WebSocket — это протокол для постоянного двустороннего соединения между клиентом и сервером. В отличие от обычного HTTP-запроса, соединение не закрывается после ответа, а остаётся открытым для обмена данными в реальном времени.

Когда WebSocket-приложение находится за Nginx (что бывает почти всегда), его нужно корректно проксировать. Стандартная конфигурация reverse proxy для HTTP здесь не подходит — без дополнительных настроек соединение не будет устанавливаться или будет обрываться.

В этой статье разберём, как правильно настроить reverse proxy для WebSocket в Nginx и какие подводные камни при этом бывают.

Как работает WebSocket под капотом

WebSocket начинается как обычный HTTP-запрос, но с заголовком Upgrade:

Connection: Upgrade
Upgrade: websocket

Если сервер принимает соединение, он отвечает кодом 101 Switching Protocols, после чего соединение превращается в постоянный TCP-канал.

Задача Nginx —:

  • корректно передать заголовки Upgrade и Connection,
  • не закрывать соединение по таймауту,
  • не буферизовать трафик.

Минимальная рабочая конфигурация

Пример проксирования WebSocket-сервера, работающего на 127.0.0.1:3000:

server {
    listen 80;
    server_name example.com;
 
    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_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 
        proxy_read_timeout 60s;
        proxy_send_timeout 60s;
    }
}

Это обязательный минимум, без которого WebSocket не заработает.

Зачем нужен proxy_http_version 1.1

По умолчанию Nginx использует HTTP/1.0 для проксирования.
WebSocket работает только поверх HTTP/1.1, поэтому:

proxy_http_version 1.1;

— обязательная директива.

Правильная передача заголовков Upgrade

Ключевые строки:

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";

Без них:

  • сервер не увидит запрос на upgrade,
  • клиент получит ошибку при установке соединения.

Если WebSocket работает нестабильно — проверь эти строки в первую очередь.

Отключение буферизации

Для WebSocket важно, чтобы данные передавались сразу, а не накапливались в буферах Nginx:

proxy_buffering off;

Полная версия блока:

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_buffering off;
 
    proxy_read_timeout 1h;
    proxy_send_timeout 1h;
}

Таймауты и обрывы соединения

По умолчанию Nginx может закрыть «долгое» соединение.
Для WebSocket это нормально, если:

  • нет трафика,
  • соединение живёт долго.

Рекомендуемые значения:

proxy_read_timeout 3600s;
proxy_send_timeout 3600s;

Или больше — в зависимости от сценария.

WebSocket + HTTPS (wss://)

Для HTTPS-соединений ничего принципиально не меняется. Главное — чтобы SSL был настроен корректно:

server {
    listen 443 ssl http2;
    server_name example.com;
 
    ssl_certificate /path/fullchain.pem;
    ssl_certificate_key /path/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_buffering off;
    }
}

Клиент будет подключаться по wss://example.com/ws.

Несколько WebSocket-сервисов

Если нужно проксировать разные сервисы:

location /chat/ {
    proxy_pass http://127.0.0.1:3001;
    include websocket.conf;
}
 
location /notifications/ {
    proxy_pass http://127.0.0.1:3002;
    include websocket.conf;
}

Где websocket.conf:

proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_buffering off;
proxy_read_timeout 1h;

Типичные ошибки

WebSocket не подключается вообще

  • забыли proxy_http_version 1.1
  • нет Upgrade / Connection

Соединение обрывается

  • слишком маленький proxy_read_timeout
  • включена буферизация

Работает локально, но не через Nginx

  • Nginx не передаёт заголовки
  • конфликт location-блоков

Итоги

  • WebSocket требует особой настройки reverse proxy.
  • Обязательны Upgrade, Connection и HTTP/1.1.
  • Таймауты и буферизация критичны для стабильности.
  • Nginx отлично справляется с WebSocket при правильной конфигурации.

Это базовая, но полностью рабочая конфигурация, которая подходит для большинства real-time приложений: чатов, нотификаций, стриминга событий и live-дашбордов.

9 минут чтения
Средний рейтинг статьи — 4.7

Настроить мониторинг за 30 секунд

Надежные оповещения о даунтаймах. Без ложных срабатываний