streamflow/docs/BUILD.md
2025-12-17 00:42:43 +00:00

11 KiB

Build Guide - IPTV Streaming Application

Quick Start

Docker Build & Run

# Build the Docker image
docker-compose build

# Start the container
docker-compose up -d

# View logs
docker-compose logs -f

# Stop the container
docker-compose down

Access the application at: http://localhost:12345


PWA Deployment

1. Build for Production

# Build optimized production bundle
docker-compose build --no-cache

# Or build frontend separately
cd frontend
npm run build

2. Generate PWA Icons

Replace placeholder icons in frontend/public/icons/ with actual icons:

Required sizes:

  • 72x72, 96x96, 128x128, 144x144, 152x152, 192x192, 384x384, 512x512

Tools:

# Install PWA asset generator
npm install -g pwa-asset-generator

# Generate icons from source image
pwa-asset-generator source-icon.png frontend/public/icons --icon-only --manifest frontend/public/manifest.json

3. Android APK Build

Prerequisites

  • Node.js 18+
  • Android Studio or Capacitor CLI

Steps

# Install Capacitor
npm install -g @capacitor/cli @capacitor/core @capacitor/android

# Initialize Capacitor in frontend directory
cd frontend
npx cap init StreamFlow tv.streamflow.app

# Add Android platform
npx cap add android

# Build frontend
npm run build

# Copy web assets to Android
npx cap copy android

# Open in Android Studio
npx cap open android

In Android Studio:

  1. Build → Generate Signed Bundle / APK
  2. Select APK
  3. Create keystore (first time) or use existing
  4. Build Release APK
  5. APK will be in frontend/android/app/build/outputs/apk/release/

Alternative: Cordova Build

# Install Cordova
npm install -g cordova

# Create Cordova project
cordova create streamflow tv.streamflow.app StreamFlow

# Copy built files to www/
cp -r frontend/dist/* streamflow/www/

# Add Android platform
cd streamflow
cordova platform add android

# Build APK
cordova build android --release

# Sign APK (optional)
jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 \
  -keystore my-release-key.keystore \
  platforms/android/app/build/outputs/apk/release/app-release-unsigned.apk \
  alias_name

4. Linux AppImage Build

Prerequisites

  • Node.js 18+
  • Electron
  • electron-builder

Steps

# Install Electron globally
npm install -g electron electron-builder

# Create Electron wrapper
cd /home/iulian/projects/tv
mkdir electron-app
cd electron-app

# Initialize package.json
cat > package.json << 'EOF'
{
  "name": "streamflow",
  "version": "1.0.0",
  "description": "IPTV Streaming Application",
  "main": "main.js",
  "scripts": {
    "start": "electron .",
    "build": "electron-builder --linux AppImage"
  },
  "build": {
    "appId": "tv.streamflow.app",
    "productName": "StreamFlow",
    "linux": {
      "target": ["AppImage"],
      "category": "AudioVideo",
      "icon": "../frontend/public/icons/icon-512x512.png"
    }
  },
  "devDependencies": {
    "electron": "^28.0.0",
    "electron-builder": "^24.9.0"
  }
}
EOF

# Create main.js
cat > main.js << 'EOF'
const { app, BrowserWindow } = require('electron');
const path = require('path');

function createWindow() {
  const mainWindow = new BrowserWindow({
    width: 1280,
    height: 720,
    webPreferences: {
      nodeIntegration: false,
      contextIsolation: true
    },
    icon: path.join(__dirname, '../frontend/public/icons/icon-512x512.png')
  });

  // Load from Docker container
  mainWindow.loadURL('http://localhost:12345');
  
  // Uncomment for development
  // mainWindow.webContents.openDevTools();
}

app.whenReady().then(createWindow);

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

app.on('activate', () => {
  if (BrowserWindow.getAllWindows().length === 0) {
    createWindow();
  }
});
EOF

# Install dependencies
npm install

# Build AppImage
npm run build

Output: electron-app/dist/StreamFlow-1.0.0.AppImage

Run AppImage:

chmod +x StreamFlow-1.0.0.AppImage
./StreamFlow-1.0.0.AppImage

Testing PWA Features

1. Test Service Worker

# Start production server
docker-compose up -d

# Open browser dev tools
# Application tab → Service Workers
# Should see service-worker.js registered

2. Test Offline Functionality

  1. Open http://localhost:12345
  2. Open DevTools → Network tab
  3. Check "Offline" checkbox
  4. Refresh page
  5. Static assets should load from cache

3. Test Install Prompt

Desktop:

  • Chrome/Edge: Click install icon in address bar
  • Firefox: Menu → Install

Mobile:

  • Chrome Android: "Add to Home Screen"
  • iOS Safari: Share → Add to Home Screen

4. Lighthouse PWA Audit

# Install Lighthouse
npm install -g lighthouse

# Run audit
lighthouse http://localhost:12345 --view --preset=desktop

Target scores:

  • Performance: 90+
  • PWA: 100
  • Accessibility: 90+

Build Optimization

1. Reduce Bundle Size

// vite.config.js optimizations
export default {
  build: {
    rollupOptions: {
      output: {
        manualChunks: {
          'vendor-react': ['react', 'react-dom', 'react-router-dom'],
          'vendor-mui': ['@mui/material', '@emotion/react', '@emotion/styled'],
          'vendor-utils': ['zustand', 'i18next', 'react-i18next']
        }
      }
    },
    chunkSizeWarningLimit: 600
  }
};

2. Enable Compression

# Add to nginx.conf (if using nginx)
gzip on;
gzip_types text/css application/javascript application/json image/svg+xml;
gzip_min_length 1000;

# Brotli compression
brotli on;
brotli_types text/css application/javascript application/json;

3. Image Optimization

# Optimize PWA icons
npm install -g sharp-cli

# Convert to WebP
for file in frontend/public/icons/*.png; do
  sharp -i "$file" -o "${file%.png}.webp"
done

Security Hardening

1. HTTPS Setup (Production)

# Generate SSL certificate
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout ssl/nginx.key -out ssl/nginx.crt

# Update docker-compose.yml
services:
  app:
    ports:
      - "12345:12345"
      - "12346:12346"  # HTTPS port
    volumes:
      - ./ssl:/app/ssl:ro

2. Content Security Policy

Add to frontend/index.html:

<meta http-equiv="Content-Security-Policy" 
      content="default-src 'self'; 
               script-src 'self' 'unsafe-inline'; 
               style-src 'self' 'unsafe-inline'; 
               img-src 'self' data: https:; 
               connect-src 'self' http://localhost:12345">

3. Rate Limiting

Already implemented in backend:

// backend/server.js
const rateLimit = require('express-rate-limit');

const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100 // 100 requests per windowMs
});

app.use('/api/', limiter);

Debugging

1. Backend Logs

# View live logs
docker-compose logs -f app

# Filter by level
docker-compose logs app | grep ERROR

2. Frontend Development

# Run frontend dev server
cd frontend
npm run dev

# Opens at http://localhost:5173
# Hot reload enabled

3. Database Inspection

# Access container
docker exec -it tv-app-1 sh

# Open SQLite database
sqlite3 /app/data/iptv.db

# View tables
.tables

# Query users
SELECT * FROM users;

4. Network Issues

# Test backend API
curl -X POST http://localhost:12345/api/auth/register \
  -H "Content-Type: application/json" \
  -d '{"username":"test","email":"test@test.com","password":"test123"}'

# Test health endpoint
curl http://localhost:12345/health

Performance Tuning

1. Node.js Memory Optimization

# Update Dockerfile
CMD ["node", "--max-old-space-size=512", "server.js"]

2. Database Indexing

-- Run in SQLite console
CREATE INDEX idx_channels_playlist ON channels(playlist_id);
CREATE INDEX idx_channels_group ON channels(group_title);
CREATE INDEX idx_epg_channel_time ON epg_programs(channel_id, start_time);
CREATE INDEX idx_favorites_user ON favorites(user_id);

3. Caching Strategy

// Update service-worker.js for aggressive caching
const CACHE_NAME = 'streamflow-v1';
const CACHE_URLS = [
  '/',
  '/index.html',
  '/assets/index.js',
  '/assets/index.css',
  // Add static assets
];

// Cache-first strategy for assets
self.addEventListener('fetch', (event) => {
  if (event.request.url.includes('/assets/')) {
    event.respondWith(
      caches.match(event.request)
        .then(response => response || fetch(event.request))
    );
  }
});

Continuous Deployment

1. GitHub Actions CI/CD

Create .github/workflows/build.yml:

name: Build & Deploy

on:
  push:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Build Docker image
        run: docker-compose build
      
      - name: Run tests
        run: docker-compose run app npm test
      
      - name: Push to registry
        run: |
          docker tag tv-app:latest myregistry/tv-app:latest
          docker push myregistry/tv-app:latest

2. Auto-versioning

# Update version in package.json
npm version patch  # 1.0.0 → 1.0.1
npm version minor  # 1.0.0 → 1.1.0
npm version major  # 1.0.0 → 2.0.0

# Rebuild with new version
docker-compose build

Troubleshooting

Common Issues

Issue: Port 12345 already in use

# Find process using port
sudo lsof -i :12345

# Kill process
kill -9 <PID>

Issue: Permission denied on data directory

# Fix permissions
sudo chown -R 1001:1001 backend/data
chmod 755 backend/data

Issue: Frontend not loading

# Rebuild frontend
cd frontend
rm -rf dist node_modules
npm install
npm run build

# Rebuild container
docker-compose build --no-cache
docker-compose up -d

Issue: Service worker not updating

# Clear browser cache
# In DevTools: Application → Clear storage → Clear site data

# Or update service worker version
# Edit frontend/public/service-worker.js
const CACHE_NAME = 'streamflow-v2';  // Increment version

Production Deployment

1. Environment Variables

Create .env file:

NODE_ENV=production
PORT=12345
JWT_SECRET=your-secure-secret-here-change-this
DATABASE_PATH=/app/data/iptv.db
LOG_LEVEL=info
RATE_LIMIT_MAX=100
CORS_ORIGIN=https://yourdomain.com

2. Docker Swarm Deployment

# Initialize swarm
docker swarm init

# Deploy stack
docker stack deploy -c docker-compose.yml streamflow

# Scale services
docker service scale streamflow_app=3

# Update service
docker service update --image tv-app:latest streamflow_app

3. Kubernetes Deployment

# kubernetes/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: streamflow
spec:
  replicas: 3
  selector:
    matchLabels:
      app: streamflow
  template:
    metadata:
      labels:
        app: streamflow
    spec:
      containers:
      - name: streamflow
        image: tv-app:latest
        ports:
        - containerPort: 12345
        volumeMounts:
        - name: data
          mountPath: /app/data
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: streamflow-pvc

Support

For issues or questions:

  1. Check logs: docker-compose logs -f
  2. Review error messages in browser console
  3. Verify port 12345 is accessible
  4. Ensure Docker has sufficient resources (2GB+ RAM)

Happy Streaming! 🎬