Introduction
In this tutorial, you will learn how to operate a Soketi WebSocket server behind an NGINX reverse proxy server, which will be protected by SSL encryption. The SSL certificate will be created using Let's Encrypt
and is thus free. The renewal of this certificate is automated with the help of the command-line program acme.sh.
Official Documentation: https://docs.soketi.app/
Project Website: https://soketi.app/
Prerequisites
- Domain name (a subdomain is sufficient)
- Some experience with NodeJS and NPM
- A server (for example, with Hetzner Cloud)
- Debian 12 or Ubuntu 24.04 as operating system
- SSH key is recommended (see this article)
- Access to the root user or a user with sudo permissions
Example terminology
- Domain:
ws.example.com
- IPv4:
203.0.113.1
- IPv6:
2001:db8:1234::1
Step 1 - Install updates and necessary packages
Connect to the server via SSH using your IP address.
Update package lists and install updates:
sudo apt update && sudo apt upgrade -y
Then restart the server to load any updated kernel.
Next, install all necessary packages:
-
Install prerequisites
sudo apt install git python3 gcc build-essential apparmor nginx
-
Install NodeJS
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.5/install.sh | bash source ~/.bashrc nvm install 18 && nvm use 18
-
Install the two NodeJS packages
soketi
andpm2
:npm install -g @soketi/soketi npm install -g pm2
Step 2 - Create configuration for Soketi
Create a new configuration file:
nano ~/config.json
Add the following content and adjust it to your needs:
{
"host": "127.0.0.1",
"port": 6001,
"appManager": {
"driver": "array",
"options": {
"apps": [
{
"id": "my-app-id",
"key": "my-app-key",
"secret": "my-app-secret",
"name": "My App",
"enableClientMessages": true,
"enableStatistics": true
}
]
}
}
}
Save it with the key combination CTRL
+O
.
If this configuration file is used, no further configuration is required before the first start.
Step 3 - First start of the Soketi server (without PM2)
Now start the Soketi server by running the following command in a terminal:
soketi start --config="~/config.json"
Step 4 - First test of the WebSocket server with Laravel 11
Make sure you have Laravel installed.
If Laravel isn't installed yet, click here and install it now
sudo apt update && sudo apt install php php-{mbstring,xml,bcmath,mysql} mariadb-server cd ~ && php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" php composer-setup.php echo 'alias composer="php ~/composer.phar"' >> ~/.bashrc && source ~/.bashrc composer create-project --prefer-dist laravel/laravel ~/example cd ~/example
And setup a database:
sudo mysql MariaDB [(none)]> CREATE USER 'laravel'@'localhost' IDENTIFIED BY 'secure-password'; MariaDB [(none)]> GRANT ALL PRIVILEGES ON laravel.* TO 'laravel'@'localhost'; MariaDB [(none)]> CREATE DATABASE laravel; MariaDB [(none)]> exit
Add the database information in the
~/example/.env
file:DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=laravel DB_USERNAME=laravel DB_PASSWORD=secure-password
Now run:
cd ~/example && php artisan migrate
Now, configure Soketi with Laravel.
Change the following values in the ~/example/.env
file:
Add the same app ID, app key, and app secret, you also used in
~/config.json
.
BROADCAST_DRIVER=pusher
PUSHER_APP_ID=my-app-id
PUSHER_APP_KEY=my-app-key
PUSHER_APP_SECRET=my-app-secret
PUSHER_APP_CLUSTER=mt1
Check the settings in the file ~/example/config/broadcasting.php
:
<?php
return [
'connections' => [
'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' => true,
],
],
// other connections...
],
];
Step 5 - Trigger first events
You can now send the first events with your WebSocket server.
Step 6 - Configure auto-start for the Soketi server
To ensure the Soketi server starts automatically after a reboot of the server, we need to configure pm2
:
Run the following commands:
pm2 start soketi --name WebSocket-Server -- start --config="~/config.json"
pm2 startup # This activates the autostart. Follow the instructions on the screen.
Step 7 - Set up reverse proxy
Now we need to set up the reverse proxy server. This will provide the SSL connection and then forward it to the soketi server. Create a new file in the /etc/nginx/sites-available/
directory.
sudo mkdir /etc/nginx/ssl
sudo nano /etc/nginx/sites-available/soketi
Add the following content to the file:
Replace
ws.example.com
with your own domain.
server {
listen 443 ssl;
server_name ws.example.com;
ssl_certificate /etc/nginx/ssl/ws.example.com.cer;
ssl_certificate_key /etc/nginx/ssl/ws.example.com.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
proxy_pass http://localhost:6001; # Replace the port if Soketi is running on a different port
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
server {
listen 80;
server_name ws.example.com;
location / {
return 301 https://$host$request_uri;
}
}
Click here if you don't want to setup SSL
Replace
203.0.113.1
with your own IP address.server { listen 80; server_name 203.0.113.1; location / { proxy_pass http://localhost:6001; # Replace the port if soketi is running on a different port proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }
sudo ln -s /etc/nginx/sites-available/soketi /etc/nginx/sites-enabled/soketi
sudo rm /etc/nginx/sites-available/default && sudo rm /etc/nginx/sites-enabled/default
sudo nginx -t
sudo systemctl restart nginx
Step 8 - Create SSL certificate
Before you create an SSL certificate, make sure you have DNS entries that point the IP addresses of you server to your domain name.
Your DNS configuration should look like this:
# Name Type Value
ws.example.com IN A 203.0.113.1
ws.example.com IN AAAA 2001:db8:1234::1
If dig ws.example.com
shows the correct IP address, you can create the certificate. Propagation can take a while.
To create the certificate, we use the shell script acme.sh
. Install it with the following command:
curl https://get.acme.sh | sh -s email=<your-email-address>
You will receive reminders at this email address when a certificate expires or if there are issues with renewal.
systemctl stop nginx && acme.sh --issue -d ws.example.com --standalone --server letsencrypt
acme.sh --install-cert -d ws.example.com --cert-file /etc/nginx/ssl/ws.example.com.cer --key-file /etc/nginx/ssl/ws.example.com.key --fullchain-file /etc/nginx/ssl/fullchain.pem --reloadcmd "systemctl reload nginx"
sudo systemctl restart nginx
Your WebSocket server is now equipped with SSL encryption. In the Laravel configuration, you need to change the port to 443
.
Conclusion
You have successfully installed Soketi and setup an SSL certificate. When you access ws.example.com
in a web browser, you should get "OK" which means that the web socket is available.