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

ChristianPav's avatar

Deploying Soketi on Forge

I followed this tutorial to use soketi on my site in forge and my WebSockets aren't connecting. My final nginx file looks like this:

# Custom Nginx Template (5035)

# FORGE CONFIG (DO NOT REMOVE!)
include forge-conf/socket.example.com/before/*;

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name socket.example.com;
    server_tokens off;
    root /home/forge/socket.example.com/;

    # FORGE SSL (DO NOT REMOVE!)
    ssl_certificate /etc/nginx/ssl/socket.example.com/1430450/server.crt;
    ssl_certificate_key /etc/nginx/ssl/socket.example.com/1430450/server.key;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;
    ssl_dhparam /etc/nginx/dhparams.pem;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options "nosniff";

    index index.html index.htm index.php;

    charset utf-8;

    # FORGE CONFIG (DO NOT REMOVE!)
    include forge-conf/socket.example.com/server/*;

    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;
    }

    access_log off;
    error_log  /var/log/nginx/socket.example.com-error.log error;
}

# FORGE CONFIG (DO NOT REMOVE!)
include forge-conf/socket.example.com/after/*;

My pusher env vars

PUSHER_HOST=socket.example.com
PUSHER_PORT=80

Everthing is setup how it should be according to the tutorial but I always get this error: WebSocket connection to 'wss://socket.example.com:80/app/app-key?protocol=7&client=js&version=7.0.6&flash=false' failed:

0 likes
5 replies
ChristianPav's avatar

Okay I my PUSHER_PORT was set to 80 when I enabled SSL so I needed to set it to 443.

1 like
UpFlat's avatar

@christianpav could you share all of your configs like broadcasting.php, .env, echo config on client side etc. please? I followed the same tutorial and I'm trying to enable ssl but i can't get it to work.

ChristianPav's avatar
ChristianPav
OP
Best Answer
Level 12

@UpFlat Certainly, I did change from using port 80/443 to using 6001/6002 though I'm not sure it makes a huge difference as long as your .env is right.

Websocket server nginx config:

# Custom Nginx Template (5035)

# FORGE CONFIG (DO NOT REMOVE!)
include forge-conf/socket.example.com/before/*;

server {
    listen 6002 ssl http2;
    listen [::]:6002 ssl http2;
    server_name socket.example.com;
    server_tokens off;
    root /home/forge/socket.example.com/;

    # FORGE SSL (DO NOT REMOVE!)
    ssl_certificate /etc/nginx/ssl/socket.example.com/1431865/server.crt;
    ssl_certificate_key /etc/nginx/ssl/socket.example.com/1431865/server.key;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS_AES_256_GCM_SHA384:TLS-AES-256-GCM-SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS-CHACHA20-POLY1305-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA;
    ssl_prefer_server_ciphers on;
    ssl_dhparam /etc/nginx/dhparams.pem;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options "nosniff";

    index index.html index.htm index.php;

    charset utf-8;

    # FORGE CONFIG (DO NOT REMOVE!)
    include forge-conf/socket.example.com/server/*;

    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;
    }

    access_log off;
    error_log  /var/log/nginx/socket.example.com-error.log error;
}

# FORGE CONFIG (DO NOT REMOVE!)
include forge-conf/socket.example.com/after/*;

supervisor deamon setup: Make sure stopwaitsecs is set to 60 I had a problem where I had multiple instances of the websockets running at the same time causing issues of messages sometimes not getting broadcasted.

[program:daemon-689926]
command=/home/forge/.yarn/bin/soketi-pm2 start

process_name=%(program_name)s_%(process_num)02d
autostart=true
autorestart=true
user=forge
numprocs=1
startsecs=1
redirect_stderr=true
stdout_logfile=/home/forge/.forge/daemon-689926.log
stopwaitsecs=60
stopsignal=SIGINT
stopasgroup=true
killasgroup=true
minfds=10240
environment=SOKETI_DEBUG=1,SOKETI_ADAPTER_DRIVER=cluster,SOKETI_RATE_LIMITER_DRIVER=cluster,SOKETI_DEFAULT_APP_SECRET=my-custom-secret

.env setup

PUSHER_APP_KEY=app-key
PUSHER_APP_ID=app-id
PUSHER_APP_SECRET=my-custom-secret
PUSHER_HOST=socket.example.com
PUSHER_SCHEME=https
PUSHER_PORT=6002

# I just updated to vite, but replace with MIX_ if you're still using mix.
VITE_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
VITE_PUSHER_HOST="${PUSHER_HOST}"
VITE_PUSHER_PORT="${PUSHER_PORT}"

config/broadcasting.php

[
  'connections' => [
      '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',
            ],
        ],
  ]
]

app.js


import Pusher from 'pusher-js';
import Echo     from 'laravel-echo';

window.Pusher = Pusher;

window.Echo = new Echo({
    broadcaster: 'pusher',
    key: import.meta.env.VITE_PUSHER_APP_KEY, // this is different for mix
    wsHost: import.meta.env.VITE_PUSHER_HOST,
    wsPort: import.meta.env.VITE_PUSHER_PORT,
    wssPort: import.meta.env.VITE_PUSHER_PORT,
    forceTLS: false,
    encrypted: true,
    disableStats: true,
    enabledTransports: ['ws', 'wss'],
});

I think that's about it

2 likes
UpFlat's avatar

@ChristianPav thank you very much. It's working now. Only change I had to make (besides your configs) is to open port 6002 instead of 6001 under Networks in Forge.

BradleyBernard's avatar

This worked for me as well, but I had my root domain having a wildcard SSL cert, which messed up the socket.my-domain.com. I had to re-issue a new SSL cert for my main domain, but remove the wildcard domain on it: *.my-domain.com was removed from the LetsEncrypt domain(s) input on Forge when creating the SSL certs

Please or to participate in this conversation.