Add Laravel WebSockets to Sail in 5 mins

D Terumalai
3 min readApr 30, 2021
Pattern photo created by bublikhaus — www.freepik.com

Since Laravel Sail has been released, using docker environments has never been so easy to use to develop your web applications. Today I will share with you how to easily add Laravel WebSockets to Laravel Sail.

Requirements

I will assume that Laravel Sail is already installed but if that’s not the case, just follow the official documentation https://laravel.com/docs/8.x/sail.

Install the dependencies

Let’s start by installing Laravel WebSockets and Pusher:

vendor/bin/sail composer require pusher/pusher-php-server beyondcode/laravel-websockets

Publish provider’s files

Next step is to publish the needed file for Laravel WebSocket and Laravel Sail.

vendor/bin/sail artisan vendor:publish --provider="BeyondCode\LaravelWebSockets\WebSocketsServiceProvider" --tag="migrations"

This will automatically create a migration file, which you can run.

vendor/bin/sail artisan migrate

Next we need the config file.

vendor/bin/sail artisan vendor:publish --provider="BeyondCode\LaravelWebSockets\WebSocketsServiceProvider" --tag="config"

This will create a file config/websockets.php. And finally, we need to publish Laravel Sail Dockerfiles to customise it.

vendor/bin/sail artisan sail:publish

Configure our application

Now, let’s configure our application to work with docker. First, let’s head to our .env file and change that line.

BROADCAST_DRIVER=pusher...PUSHER_APP_ID=12345
PUSHER_APP_KEY=12345
PUSHER_APP_SECRET=12345

As explained in Laravel WebSockets documentation, it can be used as a Pusher replacement (https://beyondco.de/docs/laravel-websockets/basic-usage/pusher) . Next, we need to adapt a bit our config/broadcasting.php file.

Let’s change this part.

'pusher' => [
'driver' => 'pusher',
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'options' => [
'cluster' => env('PUSHER_APP_CLUSTER'),
'useTLS' => false,
'encrypted' => false,
'host' => '127.0.0.1',
'port' => 6001,
'scheme' => 'http'
],
],

Note: I am assuming that we are only using Laravel Sail for local development, therefore we can downgrade our websockets protocol to not use TLS and encryption.

Modify Laravel Sail Dockerfile and docker-compose.yml

To make things easier, let’s quickly modify two files. First, let’s add those lines to docker/7.4/supervisord.conf.

[program:websockets]
command=/usr/bin/php /var/www/html/artisan websockets:serve
numprocs=1
autostart=true
autorestart=true
user=sail

This will automatically start our Laravel WebSockets server so we don’t need to do it manually every time we start our container.

The second file we need to modify, is docker-compose.yml. Add an additional port for laravel.test and modify the path to the Dockerfile.

laravel.test:
build:
context: ./docker/7.4
dockerfile: Dockerfile
args:
WWWGROUP: '${WWWGROUP}'
image: sail-7.4/app
ports:
- '${APP_PORT:-80}:80'
- '${LARAVEL_WEBSOCKETS_PORT:-6001}:6001'

Finally, to apply the changes, let’s run:

vendor/bin/sail up -d --build

This will rebuild laravel.test container and use our modifed supervisord.conf file.

Check that everything works as expected by going to http://localhost/laravel-websockets and connecting (use port 6001). If everything went fine, you should be able to connect!

Bonus: configure the client part

First, let’s install the needed NPM packages.

npm install --save-dev laravel-echo pusher-js

We are almost done, the only remaining part is the config part. Open resources/js/bootstrap.js, uncomment those lines and modify them slightly.

import Echo from 'laravel-echo'; window.Pusher = require('pusher-js'); window.Echo = new Echo({
broadcaster: 'pusher',
key: process.env.MIX_PUSHER_APP_KEY,
forceTLS: false,
wsHost: 127.0.0.1,
wsPort: 6001,
encrypted: false
});

For usage in your code, please refer to the official documentation (https://laravel.com/docs/8.x/broadcasting#listening-for-event-broadcasts).

If you use Vue.js, I advise you to add this snippet to your app.js config file instead.

Vue.prototype.$echo = new Echo({
broadcaster: 'pusher',
key: process.env.MIX_PUSHER_APP_KEY,
forceTLS: false,
wsHost: 127.0.0.1,
wsPort: 6001,
encrypted: false
});

Then, in any component you can use it like this for example:

mounted() {
this.$echo.channel('notifications')
.listen('NewNotification', (e: Event) => {
//Hand event
});
}

Conclusion

As you can see, it’s very easy to add Laravel WebSockets to Laravel Sail but keep in mind that those configurations and setups should NEVER be used in production because you should only rely on wss which is websockets over TLS to encrypt the protocol (https://javascript.info/websocket) instead of ws like our setup.

I would strongly advise to read Christophe Rumpel post about “Laravel Real Time Notifications” (https://christoph-rumpel.com/2020/11/laravel-real-time-notifications).

--

--

D Terumalai

Senior Software Developer at SIB Swiss Institute of Bioinformatics