Configure Deno WebSocket connections for real-time applications with clustering and production deployment

Intermediate 45 min Apr 11, 2026 936 views
Ubuntu 24.04 Debian 12 AlmaLinux 9 Rocky Linux 9

Set up production-ready Deno WebSocket servers with authentication, clustering, and load balancing for real-time applications. Complete with systemd service configuration and NGINX reverse proxy setup.

Prerequisites

  • Root or sudo access
  • Basic knowledge of JavaScript/TypeScript
  • Understanding of WebSocket protocol
  • Familiarity with systemd services

What this solves

Real-time applications need WebSocket connections to handle bidirectional communication between clients and servers. Deno provides excellent WebSocket support, but production deployments require proper clustering, authentication, and load balancing. This tutorial shows you how to build a scalable WebSocket server with Deno that handles multiple connections, implements security middleware, and deploys with high availability.

Step-by-step installation

Install Deno runtime

Download and install the latest Deno version directly from the official repository.

curl -fsSL https://deno.land/x/install/install.sh | sh

Add Deno to your system PATH for all users.

sudo mv ~/.deno/bin/deno /usr/local/bin/
deno --version

Create WebSocket server directory structure

Set up the application directory with proper permissions for the deployment user.

sudo mkdir -p /opt/websocket-server
sudo chown $USER:$USER /opt/websocket-server
cd /opt/websocket-server
mkdir -p src middleware config logs

Build WebSocket server with connection handling

Create the main server file with WebSocket upgrade handling and broadcasting capabilities.

import { serve } from "https://deno.land/std@0.208.0/http/server.ts";
import { authenticateConnection } from "./middleware/auth.ts";
import { WebSocketManager } from "./websocket-manager.ts";

const PORT = parseInt(Deno.env.get("PORT") || "8080");
const wsManager = new WebSocketManager();

async function handler(req: Request): Promise

Implement WebSocket connection manager

Create a manager class to handle multiple connections, broadcasting, and cleanup.

interface Connection {
  socket: WebSocket;
  userId: string;
  lastPing: number;
  rooms: Set

Create authentication middleware

Implement JWT-based authentication for WebSocket connections with token validation.

import { verify } from "https://deno.land/x/djwt@v3.0.1/mod.ts";

interface AuthResult {
  success: boolean;
  userId?: string;
  error?: string;
}

const JWT_SECRET = Deno.env.get("JWT_SECRET") || "your-secret-key-change-this";

export async function authenticateConnection(req: Request): Promise

Create environment configuration

Set up environment variables for production deployment with security settings.

PORT=8080
JWT_SECRET=your-very-secure-secret-key-change-this-in-production
NODE_ENV=production
LOG_LEVEL=info
MAX_CONNECTIONS=1000
PING_INTERVAL=30000
CONNECTION_TIMEOUT=60000

Create clustering script for load balancing

Implement a cluster manager to run multiple Deno processes for high availability.

import { serve } from "https://deno.land/std@0.208.0/http/server.ts";

const CLUSTER_SIZE = parseInt(Deno.env.get("CLUSTER_SIZE") || "4");
const BASE_PORT = parseInt(Deno.env.get("BASE_PORT") || "8080");
const workers: Deno.ChildProcess[] = [];

async function startWorker(port: number): Promise

Configure systemd service

Create a systemd service file for automatic startup and process management.

[Unit]
Description=Deno WebSocket Server
After=network.target
Wants=network.target

[Service]
Type=simple
User=www-data
Group=www-data
WorkingDirectory=/opt/websocket-server
EnvironmentFile=/opt/websocket-server/.env
ExecStart=/usr/local/bin/deno run --allow-net --allow-env --allow-read cluster.ts
Restart=always
RestartSec=10
KillMode=mixed
KillSignal=SIGTERM
TimeoutStopSec=30
LimitNOFILE=65536

# Security settings
NoNewPrivileges=yes
PrivateTmp=yes
ProtectSystem=strict
ProtectHome=yes
ReadWritePaths=/opt/websocket-server/logs

# Logging
StandardOutput=journal
StandardError=journal
SyslogIdentifier=websocket-server

[Install]
WantedBy=multi-user.target

Set proper ownership and permissions for the service files.

sudo chown -R www-data:www-data /opt/websocket-server
sudo chmod 755 /opt/websocket-server
sudo chmod 644 /opt/websocket-server/.env
sudo systemctl daemon-reload
sudo systemctl enable websocket-server

Configure NGINX reverse proxy

Set up NGINX to handle WebSocket proxying with load balancing across multiple Deno processes.

sudo apt update
sudo apt install -y nginx
sudo dnf install -y nginx

Create the NGINX configuration with WebSocket support and upstream load balancing.

upstream websocket_backend {
    least_conn;
    server 127.0.0.1:8080 max_fails=3 fail_timeout=30s;
    server 127.0.0.1:8081 max_fails=3 fail_timeout=30s;
    server 127.0.0.1:8082 max_fails=3 fail_timeout=30s;
    server 127.0.0.1:8083 max_fails=3 fail_timeout=30s;
}

server {
    listen 80;
    server_name example.com www.example.com;
    
    # Rate limiting
    limit_req_zone $binary_remote_addr zone=ws_limit:10m rate=10r/s;
    
    # Security headers
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";
    
    location /ws {
        limit_req zone=ws_limit burst=20 nodelay;
        
        # WebSocket proxy settings
        proxy_pass http://websocket_backend;
        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;
        
        # WebSocket specific timeouts
        proxy_read_timeout 3600s;
        proxy_send_timeout 3600s;
        proxy_connect_timeout 10s;
        
        # Prevent proxy buffering
        proxy_buffering off;
    }
    
    location /health {
        proxy_pass http://websocket_backend;
        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;
    }
    
    location / {
        return 404;
    }
}

# HTTPS configuration (add SSL certificates)
server {
    listen 443 ssl http2;
    server_name example.com www.example.com;
    
    # SSL configuration
    ssl_certificate /etc/ssl/certs/example.com.crt;
    ssl_certificate_key /etc/ssl/private/example.com.key;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;
    ssl_session_cache shared:SSL:10m;
    
    # Rate limiting
    limit_req_zone $binary_remote_addr zone=wss_limit:10m rate=10r/s;
    
    # Security headers
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";
    
    location /ws {
        limit_req zone=wss_limit burst=20 nodelay;
        
        proxy_pass http://websocket_backend;
        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;
        
        proxy_read_timeout 3600s;
        proxy_send_timeout 3600s;
        proxy_connect_timeout 10s;
        proxy_buffering off;
    }
    
    location /health {
        proxy_pass http://websocket_backend;
        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;
    }
}

Enable the site and restart NGINX.

sudo ln -s /etc/nginx/sites-available/websocket-server /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx

Set up monitoring and logging

Create log rotation and monitoring scripts to track WebSocket connections and performance.

/opt/websocket-server/logs/*.log {
    daily
    rotate 30
    compress
    delaycompress
    missingok
    notifempty
    create 644 www-data www-data
    postrotate
        systemctl reload websocket-server
    endscript
}

Create a monitoring script to check connection health.

#!/bin/bash
# WebSocket server monitoring script

Automated install script

Run this to automate the entire setup

Don't want to manage this yourself?

We handle infrastructure for businesses that depend on uptime. Fully managed, with one fixed contact who knows your setup.

You get one fixed contact who knows your setup

Rotterdam 04:21 · reachable in a message, no ticket form