Running Laravel Websockets in production
Tags: Websockets, Beyondcode, Laravel, PHP, Pusher

Laravel websockets by beyondcode is a pretty good package for running your own pusher websockets server, today I am going to show you how to run one in your own production server. This tutorial assumes that you are using a VPS and not a shared server, but if you find a way to execute the steps below from a shared server then great. Secondly we are only focusing on running the websockets in production, I assume you are already familiar with setting up pusher, and Laravel-websockets in Laravel. If not please check the links below.

Requirements

Laravel websockets — The installation guide can be found here Supervisor Reverse proxy server, such as nginx, (apache2 — mod_proxy)

Step 1 — Installing Laravel websockets

Please visit the guide above to install Laravel websockets.

Step 2— Installing supervisor

Supervisor is a process control system that allows the system to monitor applications and make sure they are always running. This will ensure that whenever the application terminates unexpectedly it can always be restarted.

You can follow this installation guide to see how you can install one for your system. Here is a summary.

apt install supervisor

Once supervisor has been installed we now need to configure it to run the websockets. To confirm if supervisor is installed type the following using

supervisorctl status

Navigate to the configuration cd /etc/supervisor/conf.d/

Let’s add the configurations for supervisor.

touch websockets.conf

Use any text editor to edit the websockets.conf file above, I prefer nano

nano websockets.conf

Then add the following configuration options

[program:laravel-websockets]

command=php /path/to/project artisan websockets:serve --host 127.0.0.1 --port 6000

numprocs=1

user=[user]

autostart=true

autorestart=true

stderr_logfile=/var/log/websockets.err.log

stdout_logfile=/var/log/websockets.out.log

Please don't set the user as root for security concerns instead use a user with limited privileges. Moreover, you can configure the port to be other than 6000. Lastly as you may have noticed the host is 127.0.0.1 there is a good reason for this, as we’ll see later.

Lastly to reload the supervisor configuration run.

service supervisor restart

Step 3 — Setting up the reverse proxy

This step will handle exposing the Laravel websockets to the internet. This will also take care of stripping the SSL certificate such that we don’t have to set up the certificate path in websockets config file.

Nginx

Please note: I don’t have much experience working with nginx and i am assuming the following would suffice, if you are more familiar with the setup, please add support for ssl certificates.

server {

listen 6001;

listen [::]:6001;



access_log /var/log/nginx/reverse-access.log;

error_log /var/log/nginx/reverse-error.log;



location / {

proxy_pass http://127.0.0.1:6000;

}

}

Apache

For apache make sure that the apache mod_proxy is enabled, a tutorial on how to do this can be found here.

We will add a new subdomain for the websockets, e.g. ws.yourwebsite.domain so that one can visit the websockets server.

Navigate into /etc/apache2/sites-available/ and a new site called websockets-default.conf

A sample configuration for the above can be as follows.



Listen 6001 <VirtualHost _default_:6001> ServerName ws.yourwebsite.domain

ProxyPass "/apps/" " ProxyPass "/app/" "ws://127.0.0.1:6000/app/"ProxyPass "/apps/" " http://127.0.0.1:6000/apps/ ..........

Finally, enable the proxy website using a2ensite websockets and restarting the apache2 server using service apache2 restart

In case of error use journalctl -xe to check the error.

Step 4— Updating the Laravel files

For the pusher use the following configuration which can be found in config/broadcasting.php

'pusher' => [

'driver' => 'pusher',

'key' => env('PUSHER_APP_KEY'),

'secret' => env('PUSHER_APP_SECRET'),

'app_id' => env('PUSHER_APP_ID'),

'options' => [

'host' => '[yourwebsite.domain]',

'cluster' => env('PUSHER_APP_CLUSTER'),

'useTLS' => true,

'port' => 6001,

'scheme' => 'https',

],

],

Set up the correct scheme if you are using http instead of https.

In your bootsrap.js file in order to use pusher use the following

import Echo from 'laravel-echo';



window.Pusher = require('pusher-js');



window.Echo = new Echo({

broadcaster: 'pusher',

key: process.env.MIX_PUSHER_APP_KEY,

cluster: process.env.MIX_PUSHER_APP_CLUSTER,

wsHost: '[yourwebsite.domain]',

encrypted: true,

wssPort: 6001,

disableStats: true,

forceTLS: true,

enabledTransports: ['ws', 'wss'],

disabledTransports: ['sockjs', 'xhr_polling', 'xhr_streaming']

});

If you don’t use an SSL certificates then use the following

import Echo from 'laravel-echo';



window.Pusher = require('pusher-js');



window.Echo = new Echo({

broadcaster: 'pusher',

key: process.env.MIX_PUSHER_APP_KEY,

cluster: process.env.MIX_PUSHER_APP_CLUSTER,

wsHost: '[yourwebsite.domain]',

encrypted: false,

wssPort: 6001,

disableStats: true,

forceTLS: false,

enabledTransports: ['ws', 'wss'],

disabledTransports: ['sockjs', 'xhr_polling', 'xhr_streaming']

});

Final thoughts

Hopefully the above works for you. Good luck.