Files
local-transcription/server/nodejs/DEPLOY.md
jknapp 478146c58d Improve UX: hide console window and fade connection status
- Hide console window on compiled desktop app (console=False in spec)
- Add 20-second auto-fade to "Connected" status in OBS display
- Keep "Disconnected" status visible until reconnection
- Add PM2 deployment configuration and documentation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-26 17:04:28 -08:00

9.1 KiB

Deploying Node.js Transcription Server

Quick Deploy with PM2

Step 1: Upload Files to Server

# From your local machine:
rsync -avz --exclude 'node_modules' --exclude 'data' \
  server/nodejs/ shadowdao@your-server:/home/shadowdao/local-transcription/server/nodejs/

Or manually upload:

  • server.js
  • package.json
  • ecosystem.config.js

Step 2: Install Dependencies

# SSH into your server
ssh shadowdao@your-server

# Navigate to directory
cd /home/shadowdao/local-transcription/server/nodejs

# Install dependencies
npm install --production

Step 3: Create Log Directory

# Create log directory if it doesn't exist
mkdir -p /home/shadowdao/logs/transcription
chmod 755 /home/shadowdao/logs/transcription

Step 4: Create Data Directory

# Create data directory for room storage
mkdir -p /home/shadowdao/local-transcription/server/nodejs/data
chmod 755 /home/shadowdao/local-transcription/server/nodejs/data

Step 5: Update ecosystem.config.js Paths

Edit ecosystem.config.js and update these paths:

cwd: '/home/shadowdao/local-transcription/server/nodejs',  // ← Your actual path
DATA_DIR: '/home/shadowdao/local-transcription/server/nodejs/data',
log_file: '/home/shadowdao/logs/transcription/app.log',  // ← Your log path

Step 6: Start with PM2

# Start the server
pm2 start ecosystem.config.js --env production

# Save PM2 configuration
pm2 save

# Set up PM2 to start on boot (first time only)
pm2 startup
# Follow the instructions it prints

# Check status
pm2 status

PM2 Management Commands

Check Status

pm2 status                    # List all apps
pm2 show transcription-server # Detailed info

View Logs

pm2 logs transcription-server           # Live logs
pm2 logs transcription-server --lines 100  # Last 100 lines
pm2 logs transcription-server --err     # Errors only

Restart/Stop

pm2 restart transcription-server
pm2 stop transcription-server
pm2 delete transcription-server  # Remove from PM2

Monitor

pm2 monit  # Real-time monitoring (CPU, memory, logs)

Update Code

# After uploading new code:
pm2 restart transcription-server

Configuration Options

Change Port

Edit ecosystem.config.js:

env_production: {
  PORT: 3001,  // ← Change port here
}

Then restart:

pm2 restart transcription-server

Increase Memory Limit

If you get "JavaScript heap out of memory" errors:

max_memory_restart: '1G',  // ← Increase from 512M
env_production: {
  NODE_OPTIONS: '--max-old-space-size=800'  // ← Increase from 400
}

Enable File Watching (Development)

watch: true,
ignore_watch: ['node_modules', 'data', 'logs'],

Warning: Don't use in production (unnecessary restarts)


Nginx Reverse Proxy (Optional)

To serve on port 80/443 with SSL:

Create Nginx Config

sudo nano /etc/nginx/sites-available/transcription

Add:

server {
    listen 80;
    server_name transcription.yourdomain.com;

    location / {
        proxy_pass http://127.0.0.1:3000;
        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_cache_bypass $http_upgrade;

        # WebSocket support
        proxy_read_timeout 86400;
    }
}

Enable:

sudo ln -s /etc/nginx/sites-available/transcription /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Add SSL with Let's Encrypt

sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d transcription.yourdomain.com

Firewall Configuration

Allow Port 3000

# UFW
sudo ufw allow 3000/tcp

# iptables
sudo iptables -A INPUT -p tcp --dport 3000 -j ACCEPT
sudo iptables-save

Or Use Nginx (Port 80/443)

sudo ufw allow 'Nginx Full'

Environment Variables

You can add environment variables in ecosystem.config.js:

env_production: {
  NODE_ENV: 'production',
  PORT: 3000,

  // Custom variables
  MAX_ROOMS: 100,
  ROOM_CLEANUP_INTERVAL: 7200000,  // 2 hours in ms
  MAX_CLIENTS_PER_ROOM: 50,

  // Data storage
  DATA_DIR: '/home/shadowdao/transcription-data',
}

Access in server.js:

const PORT = process.env.PORT || 3000;
const MAX_ROOMS = process.env.MAX_ROOMS || 100;

Monitoring & Maintenance

Check Server is Running

curl http://localhost:3000
# Should see HTML response

curl http://localhost:3000/api/list?room=test
# Should see: {"transcriptions":[]}

Check WebSocket

# Install wscat
npm install -g wscat

# Test WebSocket connection
wscat -c ws://localhost:3000/ws?room=test

Monitor Resources

pm2 monit  # PM2 built-in monitor

# Or use htop
htop  # Look for "node" process

Log Rotation

PM2 handles log rotation automatically, but you can configure it:

pm2 install pm2-logrotate

pm2 set pm2-logrotate:max_size 10M
pm2 set pm2-logrotate:retain 7
pm2 set pm2-logrotate:compress true

Troubleshooting

Server Won't Start

# Check logs
pm2 logs transcription-server --err

# Common issues:
# 1. Port already in use
sudo lsof -i :3000
# Kill the process or change port

# 2. Missing dependencies
cd /home/shadowdao/local-transcription/server/nodejs
npm install

# 3. Permission issues
chmod 755 server.js

WebSocket Not Working

# Check if server is listening
netstat -tlnp | grep 3000

# Check Nginx config if using reverse proxy
sudo nginx -t

# Check firewall
sudo ufw status

Out of Memory

# Check memory usage
pm2 show transcription-server

# Increase in ecosystem.config.js:
max_memory_restart: '1G',
NODE_OPTIONS: '--max-old-space-size=800'

# Restart
pm2 restart transcription-server

Too Many Rooms (Disk Full)

# Check data directory size
du -sh /home/shadowdao/local-transcription/server/nodejs/data

# Clean old rooms manually
cd /home/shadowdao/local-transcription/server/nodejs/data
find . -name "room_*.json" -mtime +1 -delete  # Delete files older than 1 day

Production Checklist

  • Dependencies installed (npm install --production)
  • Log directory created and writable
  • Data directory created and writable
  • Paths updated in ecosystem.config.js
  • PM2 started (pm2 start ecosystem.config.js --env production)
  • PM2 saved (pm2 save)
  • PM2 startup configured (pm2 startup)
  • Firewall configured (port 3000 or Nginx)
  • Nginx reverse proxy configured (optional)
  • SSL certificate installed (optional)
  • Test with curl http://your-server:3000
  • Test WebSocket with browser display page
  • Monitor for 24 hours to ensure stability

Backup & Restore

Backup Room Data

# Backup data directory
tar -czf transcription-backup-$(date +%Y%m%d).tar.gz \
  /home/shadowdao/local-transcription/server/nodejs/data

# Move to backup location
mv transcription-backup-*.tar.gz /home/shadowdao/backups/

Automated Backup (Cron)

crontab -e

Add:

# Backup transcription data daily at 2 AM
0 2 * * * tar -czf /home/shadowdao/backups/transcription-$(date +\%Y\%m\%d).tar.gz /home/shadowdao/local-transcription/server/nodejs/data

# Delete backups older than 7 days
0 3 * * * find /home/shadowdao/backups/transcription-*.tar.gz -mtime +7 -delete

Performance Tuning

For High Traffic (100+ concurrent users)

// In ecosystem.config.js:
max_memory_restart: '2G',
env_production: {
  NODE_OPTIONS: '--max-old-space-size=1600'
}

Cluster Mode (Multiple CPU Cores)

exec_mode: 'cluster',
instances: 2,  // Use 2 CPU cores

Warning: Cluster mode requires sticky sessions for WebSockets. Use single instance unless you implement Redis for session sharing.


Getting Help

If issues persist:

  1. Check logs: pm2 logs transcription-server
  2. Check server status: pm2 show transcription-server
  3. Test manually: node server.js (see direct output)
  4. Check Node.js version: node --version (needs 14+)
  5. Check port availability: sudo lsof -i :3000

Example Deploy Script

Create deploy.sh:

#!/bin/bash
# Deploy transcription server

SERVER="shadowdao@your-server"
REMOTE_PATH="/home/shadowdao/local-transcription/server/nodejs"

echo "Uploading files..."
rsync -avz --exclude 'node_modules' --exclude 'data' \
  ./ $SERVER:$REMOTE_PATH/

echo "Installing dependencies..."
ssh $SERVER "cd $REMOTE_PATH && npm install --production"

echo "Restarting server..."
ssh $SERVER "pm2 restart transcription-server"

echo "Checking status..."
ssh $SERVER "pm2 status transcription-server"

echo "Deployment complete!"

Make executable:

chmod +x deploy.sh

Use:

./deploy.sh

Server should now be accessible at:

  • Homepage: http://your-server:3000
  • API: http://your-server:3000/api/send
  • Display: http://your-server:3000/display?room=test