Настройка Laravel Reverb за Apache (рабочий production‑кейс)
Автор:
Eugeny Nosenko
Дата публикации:
2026-02-06 15:38:40 39
В этой статье разберём реальный рабочий конфиг Laravel Reverb, который используется в production и корректно работает за Apache с HTTPS и WebSocket‑проксированием.
Важно: ниже не «идеальная теоретическая схема», а практический вариант, который стабильно работает и официально поддерживается архитектурой Reverb.
Архитектура
Browser (wss://example.ru/app)
↓
Apache (SSL termination, HTTPS)
↓
Reverb (ws://0.0.0.0:6001)
↓
Laravel Events
Ключевая идея:
- TLS полностью обслуживает Apache
- Reverb работает без TLS
- Клиенты подключаются по
https / wssк домену сайта
.env — рабочая конфигурация
BROADCAST_CONNECTION=reverb REVERB_APP_ID=local REVERB_APP_KEY=local REVERB_APP_SECRET=local # Публичная точка подключения (для браузера) REVERB_HOST=example.ru REVERB_PORT=443 REVERB_SCHEME=https # Внутренний WebSocket-сервер Reverb REVERB_SERVER_HOST=0.0.0.0 REVERB_SERVER_PORT=6001
Почему это работает
В Laravel Reverb:
REVERB_HOST / PORT / SCHEMEиспользуются только как client-endpointREVERB_SERVER_HOST / PORTопределяют реальный сокет сервера
Таким образом:
- браузер подключается к
wss://example.ru/app - Apache принимает HTTPS
- Apache проксирует WebSocket в
ws://127.0.0.1:6001 - Reverb не знает про TLS и не обязан о нём знать
Это корректная и поддерживаемая схема.
Broadcasting конфигурация
config/broadcasting.php:
'default' => env('BROADCAST_CONNECTION', 'reverb'),
'connections' => [
'reverb' => [
'driver' => 'reverb',
'key' => env('REVERB_APP_KEY'),
'secret' => env('REVERB_APP_SECRET'),
'app_id' => env('REVERB_APP_ID'),
'options' => [
'host' => env('REVERB_HOST'),
'port' => env('REVERB_PORT'),
'scheme' => env('REVERB_SCHEME'),
],
],
],
Важно: здесь не используются REVERB_SERVER_* — они нужны только серверу Reverb.
Apache: проксирование WebSocket
Включаем модули
a2enmod proxy a2enmod proxy_http a2enmod proxy_wstunnel systemctl reload apache2
Конфигурация VirtualHost
<Location /app>
ProxyPass ws://127.0.0.1:6001/app
ProxyPassReverse ws://127.0.0.1:6001/app
Require all granted
</Location>
<Location /apps>
ProxyPass ws://127.0.0.1:6001/apps
ProxyPassReverse ws://127.0.0.1:6001/apps
Require all granted
</Location>
Почему нужны оба Location
Reverb использует:
/app/{key}— WebSocket handshake/apps/{id}/events— отправка событий
Если проксировать только /app, соединение установится, но события не будут доставляться.
Запуск Reverb
php artisan reverb:start
В production обязательно использовать supervisor или systemd.
Подключение фронтенда (Laravel Echo)
import Echo from 'laravel-echo';
window.Echo = new Echo({
broadcaster: 'reverb',
key: import.meta.env.VITE_REVERB_APP_KEY,
wsHost: window.location.hostname,
wsPort: 443,
wssPort: 443,
forceTLS: true,
enabledTransports: ['ws', 'wss'],
});
Клиент никогда не подключается к :6001 напрямую.
Частые ошибки
❌ Работает handshake, но нет событий
- не проксирован
/apps
❌ 403 / disconnect
- не включён
proxy_wstunnel - порт 6001 недоступен локально
❌ Mixed Content
- попытка подключиться к
ws://напрямую при HTTPS
Итог
Этот конфиг:
- используется в production
- корректно разделяет client и server настройки
- безопасен (порт 6001 закрыт извне)
- совместим с HTTPS
Главное правило:
TLS — ответственность Apache, а не Reverb
Если понимать это разделение, конфигурация становится простой и предсказуемой.