Skip to main content

πŸš€ Complete Integration Guide

NPM (Entry Point) β†’ Kubernetes (Backend) β†’ FoundationDB + Redis

Socket.IO Real-Time Chat Application


TABLE OF CONTENTS


  1. Architecture Overview
  2. Prerequisites
  3. Setup NPM (Entry Point)
  4. Deploy Kubernetes Cluster
  5. Configure Integration
  6. Testing & Validation
  7. Scaling & Performance
  8. Monitoring & Debugging
  9. Production Checklist

═══════════════════════════════════════════════════════════

1. ARCHITECTURE OVERVIEW

═══════════════════════════════════════════════════════════

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ INTERNET β”‚ β”‚ (Users' Browsers/Apps) β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ HTTPS (443) β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ NGINX PROXY MANAGER (VPS) β”‚ β”‚ β”‚ β”‚ β€’ SSL Termination (Let's Encrypt) β”‚ β”‚ β€’ DDoS Protection β”‚ β”‚ β€’ Rate Limiting β”‚ β”‚ β€’ Simple GUI Management β”‚ β”‚ β”‚ β”‚ Routes: β”‚ β”‚ chat.example.com β†’ K8s Ingress (frontend) β”‚ β”‚ ws.example.com β†’ K8s Ingress (Socket.IO) β”‚ β”‚ api.example.com β†’ K8s Ingress (REST API) β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ HTTP (Internal) β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ KUBERNETES CLUSTER (GKE/EKS/AKS) β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ NGINX Ingress Controller β”‚ β”‚ β”‚ β”‚ β€’ Internal routing β”‚ β”‚ β”‚ β”‚ β€’ Session affinity (cookie-based) β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β–Ό β–Ό β–Ό β–Ό β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚ β”‚ β”‚Frontend β”‚ β”‚Socket.IO β”‚ β”‚Socket.IO β”‚ β”‚Socket.IOβ”‚β”‚ β”‚ β”‚Pods (2) β”‚ β”‚Pod 1 β”‚ β”‚Pod 2 β”‚ β”‚Pod 3 β”‚β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚β”‚ β”‚ β”‚React/Vueβ”‚ β”‚Node.js β”‚ β”‚Node.js β”‚ β”‚Node.js β”‚β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ Redis Pub/Sub β”‚ β”‚ β–Ό β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ Redis β”‚ β”‚ β”‚ β”‚ (Adapter) β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ Store persistent data β”‚ β”‚ β–Ό β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚FoundationDB β”‚ β”‚ β”‚ β”‚ Cluster β”‚ β”‚ β”‚ β”‚ (3+ nodes) β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

═══════════════════════════════════════════════════════════

2. PREREQUISITES

═══════════════════════════════════════════════════════════

A. Domain & DNS​

β–‘ Register domain (example.com) β–‘ Access to DNS management β–‘ Subdomains:

  • chat.example.com (frontend)
  • ws.example.com (Socket.IO)
  • api.example.com (REST API)

B. Infrastructure​

β–‘ VPS for NPM (1 CPU, 1GB RAM minimum)

  • DigitalOcean: $6/month
  • Linode: $5/month
  • Hetzner: €4/month

β–‘ Kubernetes cluster

  • GKE: 3 nodes, e2-medium (~$100/month)
  • Or self-hosted k3s on VPS

C. Tools Installed​

β–‘ Docker & Docker Compose β–‘ kubectl (Kubernetes CLI) β–‘ gcloud CLI (if using GKE) β–‘ Git

═══════════════════════════════════════════════════════════

3. SETUP NPM (ENTRY POINT)

═══════════════════════════════════════════════════════════

Step 1: Install NPM on VPS​

SSH into your VPS

ssh root@YOUR_VPS_IP

Install Docker (if not installed)

curl -fsSL https://get.docker.com | sh

Create docker-compose.yml

cat > docker-compose.yml <<'EOF' version: '3.8' services: npm: image: 'jc21/nginx-proxy-manager:latest' restart: unless-stopped ports: - '80:80' - '443:443' - '81:81' environment: DB_MYSQL_HOST: "db" DB_MYSQL_PORT: 3306 DB_MYSQL_USER: "npm" DB_MYSQL_PASSWORD: "npm_secure_password_change_me" DB_MYSQL_NAME: "npm" volumes: - npm-data:/data - npm-ssl:/etc/letsencrypt

db: image: 'jc21/mariadb-aria:latest' restart: unless-stopped environment: MYSQL_ROOT_PASSWORD: 'root_secure_password_change_me' MYSQL_DATABASE: 'npm' MYSQL_USER: 'npm' MYSQL_PASSWORD: 'npm_secure_password_change_me' volumes: - npm-db:/var/lib/mysql

volumes: npm-data: npm-ssl: npm-db: EOF

Start NPM

docker-compose up -d

Check status

docker-compose ps

Step 2: Initial NPM Configuration​

Access NPM admin UI

Open browser: http://YOUR_VPS_IP:81

Default login:

Email: admin@example.com

Password: changeme

⚠️ CHANGE PASSWORD IMMEDIATELY!

Go to: Users β†’ Admin β†’ Edit β†’ Change password

Step 3: Configure DNS (Initial)​

Point all subdomains to NPM VPS IP:

A Record: chat.example.com β†’ YOUR_VPS_IP

A Record: ws.example.com β†’ YOUR_VPS_IP

A Record: api.example.com β†’ YOUR_VPS_IP

Wait for DNS propagation (5-30 minutes)

Test: ping chat.example.com

═══════════════════════════════════════════════════════════

4. DEPLOY KUBERNETES CLUSTER

═══════════════════════════════════════════════════════════

Option A: Google Kubernetes Engine (GKE)​

Authenticate

gcloud auth login gcloud config set project YOUR_PROJECT_ID

Create cluster

gcloud container clusters create chat-cluster
--zone us-central1-a
--num-nodes 3
--machine-type e2-medium
--enable-autoscaling
--min-nodes 3
--max-nodes 10
--disk-size 30

Get credentials

gcloud container clusters get-credentials chat-cluster
--zone us-central1-a

Verify connection

kubectl get nodes

Option B: Self-Hosted k3s (Cheaper)​

On a VPS (2 CPU, 4GB RAM minimum)

curl -sfL https://get.k3s.io | sh -

Get kubeconfig

sudo cat /etc/rancher/k3s/k3s.yaml > ~/.kube/config

Install from local machine

ssh root@K3S_SERVER_IP sudo cat /etc/rancher/k3s/k3s.yaml

Copy output and save to ~/.kube/config locally

Replace 127.0.0.1 with K3S_SERVER_IP

Step 2: Install Required Components​

Install cert-manager (SSL management)

kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.0/cert-manager.yaml

Install NGINX Ingress Controller

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.9.4/deploy/static/provider/cloud/deploy.yaml

Install FoundationDB Operator

kubectl apply -f https://raw.githubusercontent.com/FoundationDB/fdb-kubernetes-operator/main/config/crd/bases/apps.foundationdb.org_foundationdbclusters.yaml

kubectl apply -f https://raw.githubusercontent.com/FoundationDB/fdb-kubernetes-operator/main/config/samples/deployment.yaml

Wait for everything to be ready

kubectl wait --for=condition=ready pod
--all -n ingress-nginx --timeout=300s

Step 3: Get Kubernetes Ingress IP​

Wait for external IP (takes 2-5 minutes)

kubectl get service -n ingress-nginx ingress-nginx-controller

Note the EXTERNAL-IP

INGRESS_IP=$(kubectl get service -n ingress-nginx ingress-nginx-controller
-o jsonpath='{.status.loadBalancer.ingress[0].ip}')

echo "Kubernetes Ingress IP: $INGRESS_IP"

Step 4: Deploy Application to Kubernetes​

Clone your app repository or create structure

mkdir -p chat-app-k8s cd chat-app-k8s

Copy the kubernetes-complete-socketio-fdb.yaml from earlier

Save it as k8s-config.yaml

Update image references

sed -i 's/YOUR-PROJECT-ID/your-actual-project-id/g' k8s-config.yaml

Apply configuration

kubectl apply -f k8s-config.yaml

Wait for pods to be ready

kubectl wait --for=condition=ready pod
--all -n chat-app --timeout=300s

Check status

kubectl get all -n chat-app

Check FoundationDB

kubectl get fdb -n chat-app

═══════════════════════════════════════════════════════════

5. CONFIGURE INTEGRATION (NPM β†’ K8s)

═══════════════════════════════════════════════════════════

Step 1: Create Proxy Hosts in NPM​

Open NPM Admin UI: http://YOUR_VPS_IP:81

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ PROXY HOST 1: Frontend β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ Domain Names: chat.example.com β”‚ β”‚ Scheme: http β”‚ β”‚ Forward Hostname/IP: KUBERNETES_INGRESS_IP β”‚ β”‚ Forward Port: 80 β”‚ β”‚ β”‚ β”‚ Custom Locations: (leave empty) β”‚ β”‚ β”‚ β”‚ β˜‘ Cache Assets β”‚ β”‚ β˜‘ Block Common Exploits β”‚ β”‚ β˜‘ Websockets Support β”‚ β”‚ β”‚ β”‚ Advanced Tab - Custom Nginx Configuration: β”‚ β”‚ # Forward to Kubernetes β”‚ β”‚ 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; β”‚ β”‚ β”‚ β”‚ SSL Tab: β”‚ β”‚ β˜‘ Force SSL β”‚ β”‚ β˜‘ HTTP/2 Support β”‚ β”‚ β˜‘ HSTS Enabled β”‚ β”‚ β˜‘ Request New SSL Certificate β”‚ β”‚ Email: your-email@example.com β”‚ β”‚ β˜‘ I Agree to Let's Encrypt TOS β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ PROXY HOST 2: Socket.IO (CRITICAL!) β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ Domain Names: ws.example.com β”‚ β”‚ Scheme: http β”‚ β”‚ Forward Hostname/IP: KUBERNETES_INGRESS_IP β”‚ β”‚ Forward Port: 80 β”‚ β”‚ β”‚ β”‚ ⚠️ CRITICAL SETTINGS: β”‚ β”‚ β˜‘ Websockets Support (MUST BE CHECKED!) β”‚ β”‚ β˜‘ Block Common Exploits β”‚ β”‚ β”‚ β”‚ Advanced Tab - Custom Nginx Configuration: β”‚ β”‚ # Socket.IO requires these settings β”‚ β”‚ 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; β”‚ β”‚ β”‚ β”‚ # Long timeouts for persistent connections β”‚ β”‚ proxy_connect_timeout 7d; β”‚ β”‚ proxy_send_timeout 7d; β”‚ β”‚ proxy_read_timeout 7d; β”‚ β”‚ β”‚ β”‚ # Disable buffering β”‚ β”‚ proxy_buffering off; β”‚ β”‚ proxy_cache_bypass $http_upgrade; β”‚ β”‚ β”‚ β”‚ SSL Tab: β”‚ β”‚ β˜‘ Force SSL β”‚ β”‚ β˜‘ HTTP/2 Support β”‚ β”‚ β˜‘ HSTS Enabled β”‚ β”‚ β˜‘ Request New SSL Certificate β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ PROXY HOST 3: REST API (Optional) β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ Domain Names: api.example.com β”‚ β”‚ Scheme: http β”‚ β”‚ Forward Hostname/IP: KUBERNETES_INGRESS_IP β”‚ β”‚ Forward Port: 80 β”‚ β”‚ β”‚ β”‚ β˜‘ Block Common Exploits β”‚ β”‚ β”‚ β”‚ SSL Tab: β”‚ β”‚ β˜‘ Force SSL β”‚ β”‚ β˜‘ HTTP/2 Support β”‚ β”‚ β˜‘ Request New SSL Certificate β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Step 2: Update Kubernetes Ingress​

Edit k8s-config.yaml - change Ingress hosts

Instead of SSL in Kubernetes, terminate at NPM

Remove cert-manager annotations from Ingress

Remove TLS section from Ingress

The Ingress should only handle internal routing:


apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: socketio-ingress namespace: chat-app annotations: kubernetes.io/ingress.class: "nginx"

# Remove SSL annotations - handled by NPM
# Keep WebSocket and session affinity
nginx.ingress.kubernetes.io/websocket-services: "socketio-service"
nginx.ingress.kubernetes.io/affinity: "cookie"
nginx.ingress.kubernetes.io/session-cookie-name: "socketio-pod"

spec:

No TLS section - NPM handles SSL

rules:

  • host: ws.example.com # NPM will forward with this host header http: paths:
    • path: / pathType: Prefix backend: service: name: socketio-service port: number: 80

Apply updated config

kubectl apply -f k8s-config.yaml

═══════════════════════════════════════════════════════════

6. TESTING & VALIDATION

═══════════════════════════════════════════════════════════

Test 1: DNS Resolution​

nslookup chat.example.com

Should return NPM VPS IP

nslookup ws.example.com

Should return NPM VPS IP

Test 2: SSL Certificates​

curl -I https://chat.example.com

Should return 200 OK with valid SSL

curl -I https://ws.example.com

Should return 200 OK with valid SSL

Test 3: Frontend Loading​

Open browser: https://chat.example.com

Should load the frontend application

Test 4: Socket.IO Connection​

Open browser console (F12) on https://chat.example.com

Check Network tab β†’ Filter by WS

Should see successful WebSocket connection to wss://ws.example.com

Test 5: Multi-Pod Communication​

Open 2 browser windows

Join same room in both

Send message in one β†’ Should appear in both

Check logs to see which pods handled requests:

kubectl logs -n chat-app -l app=socketio --tail=50

Should see messages flowing between pods via Redis

Test 6: FoundationDB Persistence​

Send some messages

Kill a Socket.IO pod:

kubectl delete pod -n chat-app -l app=socketio --force

Wait for pod to restart

Join room again β†’ Should see message history!

Data persisted in FoundationDB

Test 7: Session Affinity​

Open browser with DevTools

Check Cookies β†’ Should see 'socketio-pod' cookie

All requests should go to same pod (check logs)

Test 8: Auto-Scaling​

Generate load (100+ concurrent connections)

Watch HPA scale up:

kubectl get hpa -n chat-app -w

Should see replica count increase

═══════════════════════════════════════════════════════════

7. SCALING & PERFORMANCE

═══════════════════════════════════════════════════════════

NPM Performance Tuning​

SSH into NPM VPS

ssh root@NPM_VPS_IP

Increase worker connections

docker exec -it npm sh -c "cat >> /etc/nginx/nginx.conf <<EOF worker_processes auto; worker_rlimit_nofile 65535;

events { worker_connections 4096; use epoll; } EOF"

Restart NPM

docker-compose restart npm

Kubernetes Scaling​

Manual scale Socket.IO pods

kubectl scale deployment socketio-server --replicas=10 -n chat-app

Adjust HPA thresholds

kubectl edit hpa socketio-hpa -n chat-app

Change:

minReplicas: 5

maxReplicas: 50

CPU threshold: 60%

FoundationDB Tuning​

Check status

kubectl exec -n chat-app chat-fdb-storage-1 -- fdbcli --exec "status"

For high load, increase processes

kubectl edit fdb chat-fdb -n chat-app

Change:

processCounts:

storage: 5

log: 5

stateless: 3

Redis Optimization​

Enable persistence

kubectl edit deployment redis -n chat-app

Add:

command:

- redis-server

- --appendonly yes

- --maxmemory 1gb

- --maxmemory-policy allkeys-lru

═══════════════════════════════════════════════════════════

8. MONITORING & DEBUGGING

═══════════════════════════════════════════════════════════

Monitor NPM​

View NPM logs

docker-compose logs -f npm

Check access logs

docker exec npm tail -f /data/logs/proxy-host-*_access.log

Check error logs

docker exec npm tail -f /data/logs/proxy-host-*_error.log

Monitor Kubernetes​

View all pods

kubectl get pods -n chat-app -o wide

Real-time logs from all Socket.IO pods

kubectl logs -n chat-app -l app=socketio -f

Check events

kubectl get events -n chat-app --sort-by='.lastTimestamp'

Resource usage

kubectl top pods -n chat-app kubectl top nodes

Monitor FoundationDB​

Status

kubectl exec -n chat-app chat-fdb-storage-1 --
fdbcli --exec "status minimal"

Watch transactions

kubectl exec -n chat-app chat-fdb-storage-1 --
fdbcli --exec "status json" | jq '.cluster.workload'

Monitor Redis​

Connection count

kubectl exec -n chat-app deploy/redis --
redis-cli info clients

Monitor commands

kubectl exec -n chat-app deploy/redis --
redis-cli monitor

Memory usage

kubectl exec -n chat-app deploy/redis --
redis-cli info memory

Debug Socket.IO Issues​

Test connection from within cluster

kubectl run -it --rm debug --image=curlimages/curl --restart=Never --
curl http://socketio-service.chat-app/health

Check session affinity

kubectl describe svc socketio-service -n chat-app | grep -i session

View cookie routing

kubectl logs -n ingress-nginx
deploy/ingress-nginx-controller | grep -i cookie

═══════════════════════════════════════════════════════════

9. PRODUCTION CHECKLIST

═══════════════════════════════════════════════════════════

Security​

β–‘ Changed NPM default password β–‘ Strong database passwords (use secrets) β–‘ NPM: "Block Common Exploits" enabled β–‘ Firewall: Only ports 80, 443, 22 open on NPM VPS β–‘ Kubernetes: Network policies applied β–‘ SSL: Force HTTPS on all domains β–‘ Rate limiting configured in NPM β–‘ DDoS protection (Cloudflare optional)

Reliability​

β–‘ Automated backups configured

  • FoundationDB: Daily snapshots
  • Redis: RDB snapshots
  • NPM config: Weekly exports β–‘ Health checks working on all services β–‘ HPA configured and tested β–‘ Pod disruption budgets set β–‘ Multi-zone deployment (if using GKE) β–‘ Disaster recovery plan documented

Performance​

β–‘ HTTP/2 enabled everywhere β–‘ Gzip compression enabled β–‘ CDN for static assets (optional) β–‘ Database indices optimized β–‘ Connection pooling configured β–‘ Resource limits appropriate

Monitoring​

β–‘ Logging centralized (Cloud Logging/ELK) β–‘ Metrics collection (Prometheus) β–‘ Dashboards created (Grafana) β–‘ Alerts configured:

  • Pod crashes
  • High CPU/memory
  • FoundationDB issues
  • SSL certificate expiry
  • High error rates

Documentation​

β–‘ Architecture diagram updated β–‘ Runbooks for common issues β–‘ Incident response procedures β–‘ Escalation contacts β–‘ Backup/restore procedures β–‘ Scaling procedures

═══════════════════════════════════════════════════════════

COST BREAKDOWN (Monthly)

═══════════════════════════════════════════════════════════

Small Setup (< 1k users):

  • NPM VPS (1 CPU, 1GB): $6
  • K3s VPS (2 CPU, 4GB): $12 Total: ~$18/month

Medium Setup (1k-10k users):

  • NPM VPS (2 CPU, 2GB): $12
  • GKE (3 nodes, e2-medium): $100 Total: ~$112/month

Large Setup (10k+ users):

  • NPM VPS (4 CPU, 8GB): $40
  • GKE (5-10 nodes, e2-standard-2): $300-600
  • Load Balancer: $18 Total: ~$358-658/month

═══════════════════════════════════════════════════════════

CONCLUSION

═══════════════════════════════════════════════════════════

This hybrid approach gives you:

βœ… Simple SSL management (NPM GUI) βœ… Scalable backend (Kubernetes) βœ… Reliable real-time (Socket.IO + Redis) βœ… Fast consistent storage (FoundationDB) βœ… Progressive complexity (start simple, scale up)

You now have a production-ready real-time application stack!

Next steps:

  1. Add monitoring (Prometheus + Grafana)
  2. Set up CI/CD (GitHub Actions)
  3. Configure automated backups
  4. Load test your setup
  5. Document your specific procedures

Good luck! πŸš€