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

guifsdev's avatar

Soketi + Nginx + Docker + SSL on production

I'm trying to create an application that integrates all the mentioned services in production environment, but getting "Not found" errors when broadcasting an event. I opted to using Docker in the vps since it's mentioned in the docs and has less dependencies. This command was used to run the container image and map the desired ports:

sudo docker run -d \
  --name soketi \
  -p 6001:6001 \
  -p 9601:9601 \
  quay.io/soketi/soketi:1.4-16-debian
//
$ sudo docker ps -a
CONTAINER ID   IMAGE                                 COMMAND                  CREATED       STATUS       PORTS                                                                                  NAMES
bcb6c0a2835a   quay.io/soketi/soketi:1.4-16-debian   "node /app/bin/serve…"   4 hours ago   Up 4 hours   0.0.0.0:6001->6001/tcp, :::6001->6001/tcp, 0.0.0.0:9601->9601/tcp, :::9601->9601/tcp   soketi

So, with docker ready, here comes configs.

.env:

PUSHER_APP_ID=app-id
PUSHER_APP_KEY=app-key
PUSHER_APP_SECRET=app-secret
PUSHER_HOST=mydomaindotcom
PUSHER_PORT=443
PUSHER_SCHEME=https
PUSHER_APP_CLUSTER=mt1
    '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' => env('PUSHER_SCHEME', 'https') === 'https',
        'encrypted' => true,
        'host' => env('PUSHER_HOST'),
        'port' => env('PUSHER_PORT', 443),
        'scheme' => env('PUSHER_SCHEME', 'https'),
      ],

Echo was instantiated like so:

import Echo from 'laravel-echo';

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

window.Echo = new Echo({
  broadcaster: 'pusher',
  key: process.env.MIX_PUSHER_APP_KEY,
  wsHost: window.location.hostname,
  wsPort: process.env.MIX_PUSHER_PORT,
  cluster: process.env.MIX_PUSHER_APP_CLUSTER,
  wssHost: window.location.hostname,
  wssPort: 443,
  forceTLS: true,
  disableStats: true,
  encrypted: true,
  enabledTransports: ['ws', 'wss'],
});

And Nginx config:

server {
    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
 
    server_name mydomaindotcom;

    ssl_certificate /etc/letsencrypt/live/mydomaindotcom/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/mydomaindotcom/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

    root /srv/admin/public;

    add_header X-Frame-Options "SAMEORIGIN";
	add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options "nosniff";
 
    index index.php;
 
    charset utf-8;
 
    # General web application handling
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    # WebSocket handling (if WebSocket routes are specific)
    location /app/ {
        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;
    }

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }
 
    error_page 404 /index.php;
 
    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }
 
    location ~ /\.(?!well-known).* {
        deny all;
    }

}

server {
    if ($host = mydomaindotcom) {
        return 301 https: //$host$request_uri;
    } # managed by Certbot

    listen 80;
    listen [::]:80;
    server_name mydomaindotcom;
    return 404; # managed by Certbot
}

As you can see, my intent was using a location /app/ which matches the wss url and is working properly. In network tab I get a successful wss client-server connection:

Request URL: wss: //mydomaindotcom/app/app-key?protocol=7&client=js&version=8.4.0-rc2&flash=false
Request Method: GET
Status Code: 101 Switching Protocols

The problem is that I get "Not Found" errors when an event (that broadcasts) is dispatched and as a result the payload does arrive at the frontend. The stack trace ends at #0 /srv/admin/vendor/laravel/framework/src/Illuminate/Broadcasting/BroadcastEvent.php(84): Illuminate\\Broadcasting\\Broadcasters\\PusherBroadcaster->broadcast() and begins where I dispatch the event.

I exhausted all possible alterations I could think of. I'm at the moment guessing at the possibility of the certificates not being correctly being used from inside the container.

Any help greatly appreciated.

0 likes
0 replies

Please or to participate in this conversation.