v0.4.0 UPGRADE GUIDE - nself-org/nchat GitHub Wiki

nChat v0.4.0 Upgrade Guide

Upgrading From: v0.3.0 Upgrading To: v0.4.0 Estimated Time: 15-30 minutes (excluding optional media server setup) Difficulty: Intermediate


Table of Contents

  1. Pre-Upgrade Checklist
  2. Backup Your Data
  3. Update Application Code
  4. Update Dependencies
  5. Database Migration
  6. Environment Configuration
  7. Optional: Media Server Setup
  8. Restart Services
  9. Post-Upgrade Verification
  10. Rollback Instructions
  11. Troubleshooting

Pre-Upgrade Checklist

Before starting the upgrade, ensure you have:

  • Backup of all data (database, files, configuration)
  • Access to production server (SSH, console, etc.)
  • 30 minutes of maintenance window (optional for zero-downtime)
  • Node.js 20+ and pnpm 9+ installed
  • Current version confirmed: cat package.json | grep version should show 0.3.0
  • All services running: pnpm backend:status should show all services up
  • Recent backup tested: Verify you can restore from backup

System Requirements

Minimum Requirements (same as v0.3.0):

  • Node.js: 20.0.0 or higher
  • pnpm: 9.0.0 or higher
  • PostgreSQL: 14+ (via nself CLI)
  • RAM: 4GB minimum, 8GB recommended
  • Disk: 10GB free space

Additional Requirements for E2EE:

  • No additional requirements (uses CPU for crypto operations)

Additional Requirements for Video Calls:

  • RAM: 8GB minimum, 16GB recommended (for background effects)
  • GPU: Optional but recommended for background effects
  • Bandwidth: 10 Mbps upload/download per video stream

Additional Requirements for Media Server:

  • RAM: 8GB minimum, 16GB recommended
  • CPU: 4+ cores recommended
  • Bandwidth: 100 Mbps minimum, 500 Mbps recommended
  • Public IP: Required for production TURN server
  • Ports: 3100 (HTTP), 3478 (TURN), 40000-49999 (RTC)

Backup Your Data

1. Database Backup

# Create timestamp for backup
TIMESTAMP=$(date +%Y%m%d_%H%M%S)

# Backup PostgreSQL database
cd .backend
docker exec -t nself-postgres pg_dump -U postgres nchat > "backups/nchat_${TIMESTAMP}.sql"

# Verify backup was created
ls -lh "backups/nchat_${TIMESTAMP}.sql"

2. Configuration Backup

# Backup all configuration files
mkdir -p backups/config_${TIMESTAMP}
cp .env.local "backups/config_${TIMESTAMP}/"
cp .backend/.env "backups/config_${TIMESTAMP}/"
cp -r .backend/migrations "backups/config_${TIMESTAMP}/"

3. File Storage Backup

# If using MinIO file storage
cd .backend
docker exec nself-minio mc mirror /data "backups/files_${TIMESTAMP}"

# Or if using local file storage
cp -r .backend/storage "backups/storage_${TIMESTAMP}"

4. Verify Backups

# Check backup sizes
du -sh backups/*

# Verify SQL backup is valid (check for errors)
grep -i error "backups/nchat_${TIMESTAMP}.sql"

IMPORTANT: Store backups in a safe location outside the application directory.


Update Application Code

Option A: Git Pull (Recommended)

# Stash any local changes
git stash

# Pull latest v0.4.0 code
git fetch origin
git checkout v0.4.0

# OR if on main branch
git pull origin main

# Check current version
cat package.json | grep '"version"'
# Should show: "version": "0.4.0"

Option B: Download Release

# Download v0.4.0 release
wget https://github.com/nself-org/nchat/archive/refs/tags/v0.4.0.tar.gz

# Extract
tar -xzf v0.4.0.tar.gz

# Move files (backup current first!)
mv nself-chat nself-chat-v0.3.0-backup
mv nself-chat-0.4.0 nself-chat
cd nself-chat

Update Dependencies

1. Clean Install

# Remove old dependencies
rm -rf node_modules
rm -f pnpm-lock.yaml

# Install new dependencies
pnpm install

# Verify installation
pnpm list --depth=0 | grep -E "signalapp|tensorflow|mediasoup"

Expected output should include:

@signalapp/libsignal-client 0.69.0
@tensorflow/tfjs 4.22.0
mediasoup-client 3.18.5

2. Verify pnpm Version

pnpm --version
# Should be 9.15.4 or higher

# If not, update pnpm
corepack enable
corepack prepare [email protected] --activate

3. Check for Peer Dependency Issues

# Should show no errors
pnpm install --frozen-lockfile

# If errors, run without frozen lockfile
pnpm install

Database Migration

1. Stop Application (Optional - Zero Downtime)

For zero-downtime upgrades, you can skip this step. The migrations are additive only.

# Stop frontend (optional)
# pkill -f "next dev" or pm2 stop nchat-frontend

2. Verify Database Connection

cd .backend
nself status | grep postgres
# Should show: postgres: running

# Test connection
docker exec -t nself-postgres psql -U postgres -d nchat -c "SELECT version();"

3. Review Migration Files

# List migration files for v0.4.0
ls -la migrations/013_e2ee_system.sql
ls -la migrations/014_e2ee_system.sql
ls -la migrations/015_voice_calls.sql
ls -la migrations/016_live_streaming.sql

# Preview migration (first 50 lines of E2EE migration)
head -50 migrations/014_e2ee_system.sql

4. Run Migrations

# Run all pending migrations
nself db migrate up

# Expected output:
# ✓ Running migration: 014_e2ee_system.sql
# ✓ Running migration: 015_voice_calls.sql
# ✓ Running migration: 016_live_streaming.sql
# ✓ All migrations completed successfully

5. Verify Migrations

# Check new tables were created
docker exec -t nself-postgres psql -U postgres -d nchat -c "
  SELECT table_name
  FROM information_schema.tables
  WHERE table_schema = 'public'
    AND table_name LIKE 'nchat_%'
    AND table_name IN (
      'nchat_user_master_keys',
      'nchat_identity_keys',
      'nchat_signed_prekeys',
      'nchat_one_time_prekeys',
      'nchat_signal_sessions',
      'nchat_safety_numbers',
      'nchat_e2ee_audit_log'
    )
  ORDER BY table_name;
"

# Expected output: All 7 tables listed

6. Verify Data Integrity

# Check existing data is intact
docker exec -t nself-postgres psql -U postgres -d nchat -c "
  SELECT
    (SELECT COUNT(*) FROM nchat_users) as users,
    (SELECT COUNT(*) FROM nchat_channels) as channels,
    (SELECT COUNT(*) FROM nchat_messages) as messages;
"

# Compare with your pre-upgrade counts

Environment Configuration

1. Add New Environment Variables

Edit your .env.local file and add the following:

# ═══════════════════════════════════════════════════════════════
# E2EE CONFIGURATION (v0.4.0)
# ═══════════════════════════════════════════════════════════════

# Enable end-to-end encryption feature
NEXT_PUBLIC_FEATURE_E2EE=true

# Debug mode for E2EE (set to false in production)
NEXT_PUBLIC_E2EE_DEBUG=false

# ═══════════════════════════════════════════════════════════════
# VIDEO CALLING CONFIGURATION (v0.4.0)
# ═══════════════════════════════════════════════════════════════

# Enable HD video calling
NEXT_PUBLIC_FEATURE_VIDEO_CALLS_HD=true

# Enable background effects (blur, virtual backgrounds)
NEXT_PUBLIC_FEATURE_BACKGROUND_EFFECTS=true

# Enable screen sharing
NEXT_PUBLIC_FEATURE_SCREEN_SHARING=true

# Enable screen recording
NEXT_PUBLIC_FEATURE_SCREEN_RECORDING=true

# ═══════════════════════════════════════════════════════════════
# MEDIA SERVER CONFIGURATION (v0.4.0)
# ═══════════════════════════════════════════════════════════════

# Media server URL (if using external media server)
# For local development, use default: http://localhost:3100
NEXT_PUBLIC_MEDIA_SERVER_URL=http://localhost:3100

# Media server public IP (REQUIRED for production)
# Replace with your actual public IP
MEDIA_SERVER_PUBLIC_IP=127.0.0.1

# Number of MediaSoup workers (1 per CPU core recommended)
MEDIASOUP_NUM_WORKERS=4

# Enable recording functionality
RECORDING_ENABLED=true

# JWT secret for media server authentication
# Generate with: openssl rand -base64 32
# IMPORTANT: Use a strong secret in production
JWT_SECRET=change-this-to-a-secure-random-string-min-32-chars

# ═══════════════════════════════════════════════════════════════
# TURN SERVER CONFIGURATION (v0.4.0)
# ═══════════════════════════════════════════════════════════════

# TURN server credential (for NAT traversal)
# Generate with: openssl rand -base64 32
TURN_CREDENTIAL=change-this-to-a-secure-turn-credential

# TURN server public IP (same as media server in most cases)
TURN_PUBLIC_IP=127.0.0.1

# TURN server URL (default for local development)
NEXT_PUBLIC_TURN_SERVER_URL=turn:localhost:3478

# STUN server URL (can use public STUN servers)
NEXT_PUBLIC_STUN_SERVER_URL=stun:stun.l.google.com:19302

2. Update AppConfig (Database)

The AppConfig schema has been extended. Update your configuration via admin panel or direct database update:

-- Update app_configuration table with new E2EE settings
UPDATE app_configuration
SET config = jsonb_set(
  jsonb_set(
    config,
    '{features,endToEndEncryption}',
    'true'
  ),
  '{encryption}',
  '{
    "enabled": true,
    "enforceForPrivateChannels": true,
    "enforceForDirectMessages": true,
    "allowUnencryptedPublicChannels": true,
    "enableSafetyNumbers": true,
    "requireDeviceVerification": false,
    "automaticKeyRotation": true,
    "keyRotationDays": 7
  }'::jsonb
)
WHERE id = 1;

-- Update video calling settings
UPDATE app_configuration
SET config = jsonb_set(
  config,
  '{videoCalls}',
  '{
    "maxParticipants": 50,
    "defaultResolution": "720p",
    "enableSimulcast": true,
    "enableBackgroundEffects": true,
    "enableScreenSharing": true,
    "enableRecording": false
  }'::jsonb
)
WHERE id = 1;

3. Validate Environment

# Run environment validation
pnpm validate:env

# For production, run production validation
pnpm validate:env:prod

Optional: Media Server Setup

The media server is optional for basic E2EE functionality but required for video calling features.

Quick Setup (Automated)

cd .backend

# Run automated setup wizard
./scripts/setup-media-server.sh

# Follow the prompts:
# 1. Enter your public IP address
# 2. Choose number of workers (default: 4)
# 3. Generate secure secrets (or provide your own)
# 4. Confirm configuration

Manual Setup

If you prefer manual setup or need custom configuration:

cd .backend

# 1. Create media server configuration
cp custom-services/media-server/.env.example custom-services/media-server/.env

# 2. Edit configuration
nano custom-services/media-server/.env

# Update these values:
# - MEDIA_SERVER_PUBLIC_IP=your.public.ip
# - JWT_SECRET=your-secure-secret
# - TURN_CREDENTIAL=your-turn-secret

# 3. Build media server
cd custom-services/media-server
pnpm install
pnpm build

# 4. Start media server
docker-compose -f ../../docker-compose.media.yml up -d

# 5. Verify media server is running
curl http://localhost:3100/api/health
# Should return: {"status": "ok"}

Skip Media Server (E2EE Only)

If you only want E2EE and not video calling:

# In .env.local, disable video features
NEXT_PUBLIC_FEATURE_VIDEO_CALLS_HD=false
NEXT_PUBLIC_FEATURE_BACKGROUND_EFFECTS=false
NEXT_PUBLIC_FEATURE_SCREEN_SHARING=false

# E2EE will work without media server
NEXT_PUBLIC_FEATURE_E2EE=true

Restart Services

1. Restart Backend Services

cd .backend

# Stop all services
nself stop

# Start all services (including new media server if enabled)
nself start

# Verify all services are running
nself status

# Check logs for any errors
nself logs | tail -50

2. Restart Frontend

Development

# Kill existing dev server
pkill -f "next dev"

# Start new dev server
pnpm dev

# Or with Turbopack (faster)
pnpm dev:turbo

Production (PM2)

# Rebuild production
pnpm build

# Restart with PM2
pm2 restart nchat-frontend

# Check status
pm2 status
pm2 logs nchat-frontend --lines 50

Production (Docker)

# Rebuild Docker image
pnpm build:docker

# Stop existing container
docker stop nself-chat

# Start new container
docker-compose up -d

# Check logs
docker logs nself-chat -f

3. Verify Services

# Check all services are responding
curl http://localhost:3000/api/health
curl http://localhost:3100/api/health  # Media server
curl http://api.localhost/healthz       # Hasura

# Check WebSocket connection
wscat -c ws://realtime.localhost
# Should connect successfully

Post-Upgrade Verification

1. Basic Functionality

# Test basic pages load
curl -I http://localhost:3000/
curl -I http://localhost:3000/chat
curl -I http://localhost:3000/settings

# Should all return 200 OK

2. Test E2EE Feature

Via Browser:

  1. Open http://localhost:3000
  2. Log in as test user ([email protected] / password123)
  3. Go to Settings → Security
  4. Click "Enable End-to-End Encryption"
  5. Enter a password (e.g., "TestPassword123")
  6. Save the recovery code shown
  7. Verify E2EE status shows "Enabled" with lock icon

Via API:

# Initialize E2EE for a user
curl -X POST http://localhost:3000/api/e2ee/initialize \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -d '{"password": "TestPassword123"}'

# Should return: {"success": true, "deviceId": "...", "recoveryCode": "..."}

3. Test Video Calling (If Media Server Enabled)

Via Browser:

  1. Open http://localhost:3000/chat
  2. Click on a DM or channel
  3. Click the video camera icon
  4. Allow camera/microphone permissions
  5. Start a test call
  6. Verify video appears
  7. Test background blur (if enabled)

Via API:

# Check media server health
curl http://localhost:3100/api/health

# Should return: {"status": "ok", "workers": 4, "rooms": 0}

# Check ICE servers
curl http://localhost:3100/api/ice-servers \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

# Should return TURN/STUN server configuration

4. Test Database Migrations

# Verify E2EE tables exist and are accessible
docker exec -t nself-postgres psql -U postgres -d nchat -c "
  SELECT COUNT(*) FROM nchat_user_master_keys;
  SELECT COUNT(*) FROM nchat_identity_keys;
  SELECT COUNT(*) FROM nchat_signal_sessions;
"

# Should return 0 for fresh install (no data yet)

5. Check Console for Errors

Open browser console (F12) and check for:

  • ❌ No red errors
  • ⚠️ Warnings are okay (deprecation warnings from dependencies)
  • ✅ Should see successful GraphQL connections

6. Monitor Performance

# Check CPU usage
top -p $(pgrep -f "next")

# Check memory usage
ps aux | grep next

# Check Docker container stats
docker stats --no-stream

# Should be similar to pre-upgrade levels

Rollback Instructions

If you encounter critical issues, you can rollback to v0.3.0.

1. Stop Services

cd .backend
nself stop
pkill -f "next dev"

2. Restore Database

# Restore from backup
cd .backend
docker exec -i nself-postgres psql -U postgres -d nchat < "backups/nchat_${TIMESTAMP}.sql"

# Verify restoration
docker exec -t nself-postgres psql -U postgres -d nchat -c "SELECT COUNT(*) FROM nchat_messages;"

3. Restore Application Code

# If using Git
git checkout v0.3.0

# If using backup directory
rm -rf nself-chat
mv nself-chat-v0.3.0-backup nself-chat
cd nself-chat

4. Restore Configuration

cp "backups/config_${TIMESTAMP}/.env.local" .
cp "backups/config_${TIMESTAMP}/.backend/.env" .backend/

5. Reinstall Dependencies

rm -rf node_modules
pnpm install

6. Restart Services

cd .backend
nself start
cd ..
pnpm dev

7. Verify Rollback

# Check version
cat package.json | grep version
# Should show: 0.3.0

# Verify application loads
curl http://localhost:3000/

Troubleshooting

Issue 1: Migration Fails

Error: migration 014_e2ee_system.sql failed

Solution:

# Check error details
nself logs postgres | tail -100

# Manually rollback failed migration
docker exec -t nself-postgres psql -U postgres -d nchat -c "
  DROP TABLE IF EXISTS nchat_user_master_keys CASCADE;
  DROP TABLE IF EXISTS nchat_identity_keys CASCADE;
  -- ... drop other new tables
"

# Re-run migration
nself db migrate up

Issue 2: E2EE Not Working

Error: "E2EE not initialized" or "Failed to encrypt message"

Solution:

# Check E2EE tables exist
docker exec -t nself-postgres psql -U postgres -d nchat -c "
  SELECT tablename FROM pg_tables WHERE schemaname = 'public' AND tablename LIKE '%e2ee%';
"

# Check browser console for errors
# Open DevTools (F12) → Console

# Verify feature flag is enabled
echo $NEXT_PUBLIC_FEATURE_E2EE
# Should output: true

# Clear browser cache and localStorage
# In browser console: localStorage.clear()

Issue 3: Media Server Not Starting

Error: Media server container exits immediately

Solution:

# Check logs
docker logs nself-media-server

# Common issues:
# 1. Port already in use
sudo lsof -i :3100
# Kill process if needed: sudo kill -9 <PID>

# 2. Missing environment variables
cd .backend/custom-services/media-server
cat .env | grep -E "PUBLIC_IP|JWT_SECRET|TURN"

# 3. Docker resource limits
docker info | grep -E "CPUs|Memory"
# Ensure Docker has enough resources (4GB+ RAM)

Issue 4: Video Call Not Connecting

Error: Video call starts but no video appears

Solution:

# 1. Check ICE servers
curl http://localhost:3100/api/ice-servers

# 2. Check browser permissions
# In browser: Settings → Site Settings → Permissions
# Ensure camera and microphone are allowed

# 3. Check network connectivity
# Open browser console during call
# Look for WebRTC errors

# 4. Test STUN/TURN connectivity
# Use online TURN test: https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/

Issue 5: High Memory Usage

Error: Application using more memory after upgrade

Solution:

# Expected memory increase:
# - E2EE: +50-100MB (crypto libraries)
# - Video calls: +100-200MB per active call
# - Background effects: +100-150MB (TensorFlow.js)

# Optimize settings:
# In .env.local
NEXT_PUBLIC_FEATURE_BACKGROUND_EFFECTS=false  # Disable if not needed
MEDIASOUP_NUM_WORKERS=2  # Reduce workers if low resources

# Restart with updated config

Issue 6: TypeScript Errors

Error: TypeScript compilation errors after upgrade

Solution:

# Clear TypeScript cache
rm -rf .next
rm -rf node_modules/.cache

# Reinstall dependencies
rm -rf node_modules
pnpm install

# Run type check
pnpm type-check

# If errors persist, check TypeScript version
pnpm list typescript
# Should be 5.7.3 or higher

Performance Tuning

For Low-Resource Environments

If running on a small VPS or limited resources:

# In .env.local

# Reduce media server workers
MEDIASOUP_NUM_WORKERS=2

# Disable resource-intensive features
NEXT_PUBLIC_FEATURE_BACKGROUND_EFFECTS=false
NEXT_PUBLIC_FEATURE_SCREEN_RECORDING=false

# Reduce video quality default
NEXT_PUBLIC_DEFAULT_VIDEO_QUALITY=360p

# Limit max participants
NEXT_PUBLIC_MAX_CALL_PARTICIPANTS=10

For High-Performance Environments

If running on dedicated servers:

# In .env.local

# Increase workers (1 per CPU core)
MEDIASOUP_NUM_WORKERS=16

# Enable all features
NEXT_PUBLIC_FEATURE_BACKGROUND_EFFECTS=true
NEXT_PUBLIC_FEATURE_SCREEN_RECORDING=true

# Increase video quality
NEXT_PUBLIC_DEFAULT_VIDEO_QUALITY=1080p

# Increase participant limit
NEXT_PUBLIC_MAX_CALL_PARTICIPANTS=50

Getting Help

If you're stuck or need assistance:

  1. Check Documentation:

  2. Search Existing Issues:

  3. Ask for Help:

  4. Report a Bug:


Post-Upgrade Checklist

After completing the upgrade, verify:

  • All services running: pnpm backend:status
  • Application loads: http://localhost:3000
  • User can log in
  • E2EE can be enabled in settings
  • Video calls can be initiated (if media server enabled)
  • No console errors in browser DevTools
  • Database has new tables (E2EE tables)
  • Existing data intact (messages, users, channels)
  • Performance is acceptable
  • Backups are stored safely
  • Monitoring/logging working (if applicable)

Congratulations! You've successfully upgraded to nChat v0.4.0.

Enjoy the new end-to-end encryption and video calling features! 🔒🎥

⚠️ **GitHub.com Fallback** ⚠️