How to deploy a production ready websockets server in 5mins
In this article, we'll show you how to deploy a production-ready WebSocket server in just ten minutes. We will also look at some examples.
Themba Mahlangu

In this post, we will look at how to quickly set up and deploy a production-grade WebSocket server. We use python/Django in the examples but this can be applied to any language supported by the pusher SDK.
We will use Soketi, an open-source, fast WebSockets server that implements the pusher protocol. Pusher is a hosted service that makes it easy to build real-time applications, they provide SDKs for most languages.
Prerequisites
-
Docker - for local testing and packaging of the app for deployment
-
Fly.io - optional - fly.io account and flyctl cli application.
Run a local server
Run the command below to start a local server. We will look at some examples of how you can test later in the article.
textdocker run -p 6001:6001 -p 9601:9601 quay.io/soketi/soketi:1.0-16-debian
Status: Downloaded newer image for quay.io/soketi/soketi:1.0-16-debian๐ตโโ๏ธ
Initiating metrics endpoints...
๐
Server is up and running!
๐ก
The Websockets server is available at 127.0.0.1:6001
๐
The HTTP API server is available at http://127.0.0.1:6001
๐
The /usage endpoint is available on port 9601.
Package
- Dockerfile *
textFROM quay.io/soketi/soketi:1.0-16-debian
ENV SOKETI_DEBUG=0
ENV SOKETI_DEFAULT_APP_KEY='PUSHER_KEY'
ENV SOKETI_DEFAULT_APP_ID='4712912'
ENV SOKETI_DEFAULT_APP_SECRET='PUSHER_SECREY'Notes
ENV - set up the environment variables for your server. Remember to keep your APP_SECRET secure!
Deploy
This is optional. In this example, we are deploying our container to fly.io. You can also deploy to any cloud provider. If you haven't already, follow the instructions here to sign up for a free account and install the flyctl cli. They have a free tier, credit cards are not required.
Run the following in a terminal from the same folder as your Dockerfile.
text$ flyctl launch
Scanning source code
Detected a Dockerfile app
> ? App Name (leave blank to use an auto-generated name): soketi
? Select region: ams (Amsterdam, Netherlands)
? Would you like to set up a Postgresql database now? No
? Would you like to deploy now? No
Your app is ready. Deploy with `flyctl deploy`Notes
flyctl launch - this will create a fly.toml configuration file for your application.
- fly.toml *
textkill_signal = "SIGINT"
kill_timeout = 5
processes = []
[env]
[experimental]
allowed_public_ports = []
auto_rollback = true
[[services]]
http_checks = []
internal_port = 6001 --> make sure this set to the correct port
processes = ["app"]
...Notes
internal_port - by default, fly expects your service to listen to requests on port 8080. Change this to port 6001.
Finally, deploy the application
text$ flyctl deploy
Remote builder fly-builder-nameless-field-1262 ready
==> Creating build contextWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
......
==> Monitoring deployment
1 desired, 1 placed, 1 healthy, 0 unhealthy [health checks: 1 total, 1 passing]
--> v0 deployed successfully
# check the deployment
$ flyctl info
App
Name = soketi
Owner = personal
Version = 0
Status = running
Hostname = soketi.fly.dev The image will be built remotely and pushed to the platform. Run flyctl info to get the status and information about your service. This will also provide the Hostname.
Are you building a SaaS product and want to launch like ASAP? Check out the Vanty Starter Kit. Our Django boilerplate has everything you need to launch your app today!
Examples
Let's look at a simple example of how to trigger events and subscribe to channels.
Triggering an event
In the example below we will trigger an event from a backend server using the python pusher library. Install the pusher library:
textpip install pusherrealtime.py
text# run pip install pusher
import pusher
def realtime_client() -> Pusher:
return pusher.Pusher(
app_id='471292',
key=PUSHER_KEY,
secret=PUSHER_SECRET,
host='soketi.fly.dev',
port=443,
ssl=True,
)service.py
textdef promo_service(channel="promotions", event='summer-promo'):
data = {"message":"launch-today with the vanty starter kit"}
realtime_client().trigger(channel, event, data) Notes
realtime_client() - a client that returns an instance of the Pusher class.
promo_service - a fake service that will push events to the promotions. In this case, the event has some data attached to it.
Subscribing to a channel
In the example below we will subscribe to and listen to any events from the promotions channel.
text# html
<script defer src="https://js.pusher.com/7.2/pusher.min.js"></script>
<script>
let _pusherClient
function pusherClient() {
if (!_pusherClient) {
_pusherClient = new Pusher(
'471292',
{
wsHost: 'soketi.fly.dev',
wsPort: 443,
wssPort: 443,
forceTLS: true,
encrypted: true,
disableStats: true,
enabledTransports: ['ws', 'wss'],
}
);
}
return _pusherClient;
}
document.addEventListener('DOMContentLoaded', function(){
// subscribe to events
const channel = this.pusherClient().subscribe('promotions')
// listen to events
channel.bind('summer-promo'), (d)=> {alert(d.message)})
})
<script>Notes
<script defer..> - we are using the pusher javascript library directly from the CDN. You can also install it from NPM.
_pusherClient - open a new connection to the server.
const channel -.. - subscribe to the channel
channel.bind - listen for events with the name 'summer-promo' and create an alert.
Conclusion
In this article, we have explored the deployment and execution of a high-quality WebSocket server, along with some python-based examples. For those seeking a cost-effective managed service, Pusher Soketi now offers a cloud service that is based on Cloudflare workers.
Useful links
Soketi Docs
Pusher SDK library docs