This guide explains how to configure Laravel Reverb to work behind Nginx with a /ws/ WebSocket path prefix.
Using a custom path helps prevent conflicts with other routes and ensures WebSocket traffic is correctly proxied. This allows to run the WebSocket traffic on the same domain as the Web Server.
Oprtional: It also demonstrates how to authenticate connections using JWT tokens.
The following Nginx block forwards all /ws/ requests to the Reverb WebSocket server running locally on port 8080:
location /ws/ {
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header Scheme $scheme;
proxy_set_header SERVER_PORT $server_port;
proxy_set_header REMOTE_ADDR $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_pass http://127.0.0.1:8080;
proxy_read_timeout 86400;
}
Use the following echo.js configuration to connect your frontend to Laravel Reverb with JWT-based authentication (optional):
import Echo from 'laravel-echo';
import Pusher from 'pusher-js';
window.Pusher = Pusher;
// if using JWT based auth
const currentUserToken = JSON.parse(localStorage.getItem('auth.token'));
window.Echo = new Echo({
broadcaster: 'reverb',
key: import.meta.env.VITE_REVERB_APP_KEY,
wsHost: import.meta.env.VITE_REVERB_HOST,
wsPort: import.meta.env.VITE_REVERB_PORT ?? 80,
wssPort: import.meta.env.VITE_REVERB_PORT ?? 443,
wsPath: import.meta.env.VITE_REVERB_PATH ?? '',
forceTLS: (import.meta.env.VITE_REVERB_SCHEME ?? 'https') === 'https',
enabledTransports: ['ws', 'wss'],
auth: {
headers: {
Authorization: 'Bearer ' + currentUserToken,
},
},
});Update your environment variables to match your setup:
BROADCAST_CONNECTION=reverb
REVERB_APP_ID=<your_app_id>
REVERB_APP_KEY=<your_app_key> # generate with ` openssl rand -hex 32`
REVERB_APP_SECRET=<your_app_secret> # generate with ` openssl rand -hex 32`
REVERB_SERVER_HOST=127.0.0.1
REVERB_SERVER_PORT=8080
REVERB_SERVER_PATH=/ws
REVERB_HOST=<your_domain>
REVERB_PORT=443
REVERB_SCHEME=https
VITE_REVERB_APP_KEY="${REVERB_APP_KEY}"
VITE_REVERB_HOST="${REVERB_HOST}"
VITE_REVERB_PORT="${REVERB_PORT}"
VITE_REVERB_SCHEME="${REVERB_SCHEME}"
VITE_REVERB_PATH=/ws
Finally, update your Reverb connection configuration to include the base path:
connections.reverb.options.base_path = env('VITE_REVERB_PATH', '').'/apps/'.env('REVERB_APP_ID')
sudo nano /etc/systemd/system/reverb.service
[Unit]
Description=Laravel Reverb WebSocket Server
After=network.target
[Service]
ExecStart=/usr/bin/php /var/www/example.test/artisan reverb:start --port=6001 --host=0.0.0.0
Restart=always
User=www-data
Group=www-data
WorkingDirectory=/var/www/example.test
[Install]
WantedBy=multi-user.target
Reference - https://dev.to/edgaras/running-laravel-reverb-in-the-background-using-systemd-3732