Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

ahmeda's avatar

Configure SSL with Soketi

I have this config.json file for Soketi that required me these things to configure the SSL:

  "ssl": [
    {
      "certPath": "", => The path to the SSL certificate file.
      "keyPath": "", => The path to the SSL key file.
      "passphrase": "", => The passphrase (if any) for the SSL key
      "caPath": "" => The path to the SSL Certificate Authority file.
    }
  ]

I need to find these files using Certbot. And I'm using EC2 linux.

I installed Certbot on my server and everything is fine.

I go to sudo vim /etc/nginx/nginx.conf and find these things there:

ssl_certificate /etc/letsencrypt/live/XXXXX/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/XXXXX/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
0 likes
38 replies
ahmeda's avatar

@Sinnbeck I do it and install the Certbot and make my Nginx as a proxy to localhost:6001 but when I tried the URL of my domain I got this error on the server side(Laravel project) but in pusher js in the console I got the connection correctly.

the error I got:

Illuminate\Broadcasting\BroadcastException: Pusher error: . 

So weird error!

my event:

class OrderStatusUpdated implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public $message = 'Order status updated';

    public function broadcastOn()
    {
        return new Channel('orders');
    }
}
ahmeda's avatar

@Sinnbeck MY Nginx config:

events {
    worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 4096;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;

    server {
        server_name  realtime.XXXX.co;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        error_page 404 /404.html;
        location = /404.html {
        }
        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
        }

        location / {
            proxy_pass             http://127.0.0.1:6001;
            proxy_read_timeout     60;
            proxy_connect_timeout  60;
            proxy_redirect         off;

            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
        }

    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/realtime.XXXX.co/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/realtime.XXXX.co/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

ahmeda's avatar

@Sinnbeck My .env file

PUSHER_APP_KEY=app-key
PUSHER_APP_ID=app-id
PUSHER_APP_SECRET=app-secret
PUSHER_HOST=realtime.XXXX.co
PUSHER_PORT=80

VITE_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
VITE_PUSHER_HOST="${PUSHER_HOST}"
VITE_PUSHER_PORT="${PUSHER_PORT}"
VITE_PUSHER_SCHEME="${PUSHER_SCHEME}"

my broadcasting.php

'pusher' => [
            'driver' => 'pusher',
            'key' => env('PUSHER_APP_KEY', 'app-key'),
            'secret' => env('PUSHER_APP_SECRET', 'app-secret'),
            'app_id' => env('PUSHER_APP_ID', 'app-id'),
            'options' => [
                'host' => env('PUSHER_HOST', '127.0.0.1'),
                'port' => env('PUSHER_PORT', 6001),
                'scheme' => env('PUSHER_SCHEME', 'http'),
                'encrypted' => true,
                'useTLS' => env('PUSHER_SCHEME', 'https') === 'https',
            ],
        ],

boostrap.js


import Echo from "laravel-echo";

import Pusher from "pusher-js";
window.Pusher = Pusher;

window.Echo = new Echo({
    broadcaster: "pusher",
    key: import.meta.env.VITE_PUSHER_APP_KEY,
    // wsHost:
    //     import.meta.env.VITE_PUSHER_HOST ??
    //     `ws-${import.meta.env.VITE_PUSHER_APP_CLUSTER}.pusher.com`,
    // wsPort: import.meta.env.VITE_PUSHER_PORT ?? 80,
    wssHost: import.meta.env.VITE_PUSHER_HOST,
    wssPort: import.meta.env.VITE_PUSHER_PORT ?? 443,
    forceTLS: true,
    // forceTLS: (import.meta.env.VITE_PUSHER_SCHEME ?? "https") === "https",
    // enabledTransports: ["ws", "wss"],
    enabledTransports: ["wss"],
});

window.Echo.channel("orders").listen("OrderStatusUpdated", (e) => {
    console.log(e);
});
ahmeda's avatar

@Sinnbeck when I change the port to 443 and make a request i got this error:

504 Gateway Time-out
nginx/1.21.6

My Laravel app is still in local not production

in laravel.log

local.ERROR: Pusher error: cURL error 28: Failed to connect to realtime.xxxxx.co port 433 after 75004 ms: Operation timed out
ahmeda's avatar

@Sinnbeck Yeah sure 100% Can I send it to you in a private way ? like If you have a temporary email I will send the domain!

Sinnbeck's avatar

@ahmeda sorry but that's not a service I provide. I have also only configured it once (using ploi), so I cannot remember 100% what I did. I just know that I use 433 as port

ahmeda's avatar

@Sinnbeck Sorry for misunderstanding just wanted to send the domain to you to make sure that is returned OK

Sinnbeck's avatar

@ahmeda no worries. Sadly I'm not at a computer currently. Is this a secret project since you can't share the domain? Something to be used internally?

ahmeda's avatar

@Sinnbeck sir it is 433 or 443 ?

cuz I change it to 443 and I got this error now :(

Pusher error: <html> <head><title>400 The plain HTTP request was sent to HTTPS port</title></head> <body> <center><h1>400 Bad Request</h1></center> <center>The plain HTTP request was sent to HTTPS port</center> <hr><center>nginx/1.20.0</center> </body> </html> .
ahmeda's avatar

@Sinnbeck I broadcasting.php there is no PUSHER_ENCRYPTED

 'pusher' => [
            'driver' => 'pusher',
            'key' => env('PUSHER_APP_KEY', 'app-key'),
            'secret' => env('PUSHER_APP_SECRET', 'app-secret'),
            'app_id' => env('PUSHER_APP_ID', 'app-id'),
            'options' => [
                'host' => env('PUSHER_HOST', '127.0.0.1'),
                'port' => env('PUSHER_PORT', 6001),
                'scheme' => env('PUSHER_SCHEME', 'http'),
                'encrypted' => true,
                'useTLS' => env('PUSHER_SCHEME', 'https') === 'https',
            ],
        ],

I put it and still the same error

Sinnbeck's avatar

Looks correct. I get OK when I visit it. Exactly the same as on my own implementation. Think the server is correctly configured Think its a php misconfiguration

These are my settings (getting port 443 and correct host from env)

                'host' => env('PUSHER_HOST', '127.0.0.1'),
                'port' => env('PUSHER_PORT', 6001),
                'scheme' => env('PUSHER_SCHEME', 'https'),
                'encrypted' => true,
                'useTLS' => true,
PUSHER_HOST='sockti.mydomain.com'
PUSHER_PORT=443
Sinnbeck's avatar

@ahmeda I know I had the same error when I was setting mine up back in the day, but I sadly cannot think of what the solution was. Can you try php artisan tinker and then config('broadcasting'); (on the server) and post the output?

ahmeda's avatar

@Sinnbeck event I got type: "connected" in Network tab in console WebSocket connection :(

Sinnbeck's avatar

@ahmeda That looks like vite's websocket server. Just to avoid confusion run npm run build

1 like
ahmeda's avatar

@Sinnbeck I got it ! this was missing:

PUSHER_SCHEME=https

But now I got nothing in JS Side

How do I know it is done but PHP? I'm monitoring Soketi And when I visit the event route I got this in terminal:

{
  name: 'App\Events\OrderStatusUpdated',
  data: '{"message":"Order status updated"}',
  channels: [ 'orders' ]
}

How time to config the js side :(

ahmeda's avatar

@Sinnbeck could you pls share your config js file while connect to pusher-js :)

Sinnbeck's avatar

@ahmeda Sure

window.Pusher = Pusher
window.Echo = new Echo({
    broadcaster: 'pusher',
    key: import.meta.env.VITE_PUSHER_APP_KEY,
    forceTLS: false,
    encrypted: import.meta.env.VITE_PUSHER_ENCRYPTED === 'true', //this is why I had that encrypted env setting :)
    wsHost: import.meta.env.VITE_PUSHER_HOST,
    wsPort: import.meta.env.VITE_PUSHER_PORT,
    wssPort: import.meta.env.VITE_PUSHER_PORT,
    disableStats: true,
    enabledTransports: ['ws', 'wss'],
})
ahmeda's avatar

@Sinnbeck THANK YOU SO MUCH, SIR :) it is working now, and i will make a complete blog post on (dev.to) how to install it and config it and will mention your name on it

THANKS again

Sinnbeck's avatar

@ahmeda Sounds good :) I was actually planning on writing a blog for ploi users myself, but never got around to it :D Post a link and I will give it a read.

Please remember to mark a best answer to set the thread as solved :)

1 like
Sinnbeck's avatar

@ahmeda looks great! I will try and remember to point to your guide when people ask for help 👍

1 like
amaelftah's avatar

@sinnbeck @ahmeda ... really thanks guys for putting up the article I wouldn't have managed to deploy soketi on ec2 without this guide

just a quick notes

  • the nginx location configuration mentioned in the article ... probably must be inside server block

  • also while am using vapor the certificates are done through aws certificate manager ... so I had to make a workaround by making a public load balancer with aws certificate then attach that load balancer to ec2

  • lastly this is how my nginx config as a reference

server { 

			server_tokens off; 
			listen       6002;
 			server_name $hostname; 
			charset utf-8;

 			location / { 
						proxy_pass             http://127.0.0.1:6001; 
						proxy_read_timeout     60; 
						proxy_connect_timeout  60;
						 proxy_redirect         off;
						 proxy_http_version 1.1; 
						proxy_set_header Upgrade $http_upgrade;
						 proxy_set_header Connection 'upgrade'; 
						proxy_set_header Host $host;
						 proxy_cache_bypass $http_upgrade;
			 }
 }

1 like

Please or to participate in this conversation.