streamflow/docs/BUILD.md

625 lines
11 KiB
Markdown
Raw Normal View History

# Build Guide - IPTV Streaming Application
## Quick Start
### Docker Build & Run
```bash
# 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
```bash
# 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:**
- [PWA Asset Generator](https://github.com/onderceylan/pwa-asset-generator)
- [RealFaviconGenerator](https://realfavicongenerator.net/)
```bash
# 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
```bash
# 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
```bash
# 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
```bash
# 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:**
```bash
chmod +x StreamFlow-1.0.0.AppImage
./StreamFlow-1.0.0.AppImage
```
---
## Testing PWA Features
### 1. Test Service Worker
```bash
# 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
```bash
# 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
```javascript
// 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
```nginx
# 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
```bash
# 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)
```bash
# 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`:
```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:
```javascript
// 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
```bash
# View live logs
docker-compose logs -f app
# Filter by level
docker-compose logs app | grep ERROR
```
### 2. Frontend Development
```bash
# Run frontend dev server
cd frontend
npm run dev
# Opens at http://localhost:5173
# Hot reload enabled
```
### 3. Database Inspection
```bash
# 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
```bash
# 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
```dockerfile
# Update Dockerfile
CMD ["node", "--max-old-space-size=512", "server.js"]
```
### 2. Database Indexing
```sql
-- 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
```javascript
// 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`:
```yaml
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
```bash
# 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
```bash
# Find process using port
sudo lsof -i :12345
# Kill process
kill -9 <PID>
```
**Issue:** Permission denied on data directory
```bash
# Fix permissions
sudo chown -R 1001:1001 backend/data
chmod 755 backend/data
```
**Issue:** Frontend not loading
```bash
# 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
```bash
# 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:
```bash
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
```bash
# 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
```yaml
# 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! 🎬**