mirror of
https://github.com/hotheadhacker/seedbox-lite.git
synced 2025-09-02 00:51:36 +03:00
Add CORS testing script for API endpoints
- Created a new script `test-cors.sh` to test CORS configuration. - Included tests for OPTIONS preflight request, actual POST request, and health endpoint. - Utilized curl for making requests to the API with appropriate headers.
This commit is contained in:
305
DOCKER.md
Normal file
305
DOCKER.md
Normal file
@@ -0,0 +1,305 @@
|
||||
# SeedBox Lite - Docker Deployment Guide
|
||||
|
||||
This guide covers deploying SeedBox Lite using Docker Compose for different environments.
|
||||
|
||||
## 🚀 Quick Start
|
||||
|
||||
### Development Environment
|
||||
```bash
|
||||
# Clone the repository
|
||||
git clone <your-repo-url> seedbox-lite
|
||||
cd seedbox-lite
|
||||
|
||||
# Start development environment with hot reload
|
||||
docker-compose up --build
|
||||
```
|
||||
|
||||
### Production Environment
|
||||
```bash
|
||||
# Start production environment with nginx proxy
|
||||
docker-compose -f docker-compose.yml -f docker-compose.prod.yml --profile production up --build -d
|
||||
```
|
||||
|
||||
## 📁 File Structure
|
||||
|
||||
```
|
||||
seedbox-lite/
|
||||
├── docker-compose.yml # Main compose file
|
||||
├── docker-compose.override.yml # Development overrides
|
||||
├── docker-compose.prod.yml # Production overrides
|
||||
├── nginx/
|
||||
│ └── nginx.conf # Production nginx config
|
||||
├── server-new/
|
||||
│ ├── Dockerfile # Backend production image
|
||||
│ ├── .dockerignore # Backend ignore patterns
|
||||
│ └── .env.docker # Backend docker env vars
|
||||
└── client/
|
||||
├── Dockerfile # Frontend production image
|
||||
├── Dockerfile.dev # Frontend development image
|
||||
├── nginx.conf # Frontend nginx config
|
||||
├── .dockerignore # Frontend ignore patterns
|
||||
└── .env.production # Frontend production env vars
|
||||
```
|
||||
|
||||
## 🛠 Configuration
|
||||
|
||||
### Environment Variables
|
||||
|
||||
#### Backend (.env.docker)
|
||||
```bash
|
||||
NODE_ENV=production
|
||||
SERVER_PORT=3001
|
||||
SERVER_HOST=0.0.0.0
|
||||
FRONTEND_URL=https://<domain>
|
||||
ACCESS_PASSWORD=test123456
|
||||
```
|
||||
|
||||
#### Frontend (.env.production)
|
||||
```bash
|
||||
VITE_API_BASE_URL=https://seedbox-api.isalman.dev
|
||||
```
|
||||
|
||||
### Custom Configuration
|
||||
1. Update domain names in environment files
|
||||
2. Modify `ACCESS_PASSWORD` for security
|
||||
3. Configure SSL certificates for HTTPS (see nginx config)
|
||||
|
||||
## 🌐 Deployment Scenarios
|
||||
|
||||
### 1. Local Development
|
||||
```bash
|
||||
# Start with hot reload and file watching
|
||||
docker-compose up --build
|
||||
|
||||
# Access:
|
||||
# Frontend: http://localhost:5174
|
||||
# Backend: http://localhost:3001
|
||||
```
|
||||
|
||||
### 2. Production without Reverse Proxy
|
||||
```bash
|
||||
# Start frontend and backend only
|
||||
docker-compose up --build -d seedbox-frontend seedbox-backend
|
||||
|
||||
# Access:
|
||||
# Frontend: http://localhost:5174
|
||||
# Backend: http://localhost:3001
|
||||
```
|
||||
|
||||
### 3. Production with Nginx Reverse Proxy
|
||||
```bash
|
||||
# Start all services including nginx
|
||||
docker-compose -f docker-compose.yml -f docker-compose.prod.yml --profile production up --build -d
|
||||
|
||||
# Access:
|
||||
# Application: http://localhost
|
||||
# All API calls proxied through nginx
|
||||
```
|
||||
|
||||
### 4. Custom Ports
|
||||
```bash
|
||||
# Override ports in docker-compose.override.yml or use environment variables
|
||||
FRONTEND_PORT=8080 BACKEND_PORT=8081 docker-compose up
|
||||
```
|
||||
|
||||
## 🔧 Container Details
|
||||
|
||||
### Backend Container (seedbox-backend)
|
||||
- **Base Image**: node:18-alpine
|
||||
- **Port**: 3001
|
||||
- **Volumes**:
|
||||
- `seedbox_data:/app/data` (torrent data)
|
||||
- `seedbox_cache:/app/cache` (cache storage)
|
||||
- `./server-new/logs:/app/logs` (application logs)
|
||||
- **Health Check**: GET /api/health
|
||||
|
||||
### Frontend Container (seedbox-frontend)
|
||||
- **Base Image**: nginx:alpine (production) / node:18-alpine (development)
|
||||
- **Port**: 80 (production) / 5174 (development)
|
||||
- **Features**:
|
||||
- Gzip compression
|
||||
- Static file caching
|
||||
- Security headers
|
||||
- React Router support
|
||||
|
||||
### Nginx Proxy Container (nginx)
|
||||
- **Base Image**: nginx:alpine
|
||||
- **Ports**: 80, 443
|
||||
- **Features**:
|
||||
- Rate limiting
|
||||
- SSL termination (when configured)
|
||||
- API and frontend routing
|
||||
- CORS handling
|
||||
|
||||
## 📊 Monitoring & Logs
|
||||
|
||||
### View Logs
|
||||
```bash
|
||||
# All services
|
||||
docker-compose logs -f
|
||||
|
||||
# Specific service
|
||||
docker-compose logs -f seedbox-backend
|
||||
docker-compose logs -f seedbox-frontend
|
||||
```
|
||||
|
||||
### Health Checks
|
||||
```bash
|
||||
# Check container health
|
||||
docker-compose ps
|
||||
|
||||
# Manual health check
|
||||
curl http://localhost:3001/api/health # Backend
|
||||
curl http://localhost:5174/health # Frontend
|
||||
```
|
||||
|
||||
### Volume Management
|
||||
```bash
|
||||
# List volumes
|
||||
docker volume ls
|
||||
|
||||
# Inspect volume
|
||||
docker volume inspect seedbox-lite_seedbox_data
|
||||
|
||||
# Backup volume
|
||||
docker run --rm -v seedbox-lite_seedbox_data:/data -v $(pwd):/backup alpine tar czf /backup/seedbox_data_backup.tar.gz -C /data .
|
||||
```
|
||||
|
||||
## 🔒 Security Features
|
||||
|
||||
### Container Security
|
||||
- Non-root user execution
|
||||
- Minimal base images (Alpine Linux)
|
||||
- Security headers configured
|
||||
- Rate limiting enabled
|
||||
|
||||
### Network Security
|
||||
- Isolated Docker network
|
||||
- CORS properly configured
|
||||
- SSL support ready (certificates needed)
|
||||
|
||||
### Data Security
|
||||
- Named volumes for persistent data
|
||||
- Proper file permissions
|
||||
- Log rotation configured
|
||||
|
||||
## 🚨 Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
#### 1. Port Conflicts
|
||||
```bash
|
||||
# Check if ports are in use
|
||||
lsof -i :3001
|
||||
lsof -i :5174
|
||||
|
||||
# Use different ports
|
||||
FRONTEND_PORT=8080 BACKEND_PORT=8081 docker-compose up
|
||||
```
|
||||
|
||||
#### 2. Permission Issues
|
||||
```bash
|
||||
# Fix volume permissions
|
||||
docker-compose exec seedbox-backend chown -R nodejs:nodejs /app/data /app/cache
|
||||
```
|
||||
|
||||
#### 3. Build Failures
|
||||
```bash
|
||||
# Clean rebuild
|
||||
docker-compose down --volumes
|
||||
docker system prune -f
|
||||
docker-compose build --no-cache
|
||||
```
|
||||
|
||||
#### 4. Network Issues
|
||||
```bash
|
||||
# Recreate network
|
||||
docker-compose down
|
||||
docker network prune
|
||||
docker-compose up
|
||||
```
|
||||
|
||||
### Debug Mode
|
||||
```bash
|
||||
# Run with debug output
|
||||
DEBUG=* docker-compose up
|
||||
|
||||
# Shell into container
|
||||
docker-compose exec seedbox-backend sh
|
||||
docker-compose exec seedbox-frontend sh
|
||||
```
|
||||
|
||||
## 🔄 Updates & Maintenance
|
||||
|
||||
### Update Application
|
||||
```bash
|
||||
# Pull latest code
|
||||
git pull
|
||||
|
||||
# Rebuild and restart
|
||||
docker-compose down
|
||||
docker-compose build --no-cache
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
### Cleanup
|
||||
```bash
|
||||
# Remove stopped containers
|
||||
docker-compose down --remove-orphans
|
||||
|
||||
# Clean unused images
|
||||
docker image prune -f
|
||||
|
||||
# Full cleanup (caution: removes volumes)
|
||||
docker-compose down --volumes
|
||||
docker system prune -a -f
|
||||
```
|
||||
|
||||
## 📝 Production Checklist
|
||||
|
||||
- [ ] Update domain names in environment files
|
||||
- [ ] Change default passwords
|
||||
- [ ] Configure SSL certificates
|
||||
- [ ] Set up log rotation
|
||||
- [ ] Configure monitoring
|
||||
- [ ] Test backup and restore procedures
|
||||
- [ ] Configure firewall rules
|
||||
- [ ] Set up automated updates
|
||||
|
||||
## 🌍 Scaling & Performance
|
||||
|
||||
### Horizontal Scaling
|
||||
```bash
|
||||
# Scale backend instances
|
||||
docker-compose up --scale seedbox-backend=3
|
||||
|
||||
# Use nginx load balancing (update nginx.conf)
|
||||
upstream backend {
|
||||
server seedbox-backend_1:3001;
|
||||
server seedbox-backend_2:3001;
|
||||
server seedbox-backend_3:3001;
|
||||
}
|
||||
```
|
||||
|
||||
### Resource Limits
|
||||
Add to docker-compose.yml:
|
||||
```yaml
|
||||
services:
|
||||
seedbox-backend:
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '1.0'
|
||||
memory: 1G
|
||||
reservations:
|
||||
cpus: '0.5'
|
||||
memory: 512M
|
||||
```
|
||||
|
||||
## 🤝 Support
|
||||
|
||||
For issues and questions:
|
||||
1. Check the troubleshooting section
|
||||
2. Review container logs
|
||||
3. Ensure all environment variables are set correctly
|
||||
4. Verify network connectivity between containers
|
||||
68
QUICKSTART.md
Normal file
68
QUICKSTART.md
Normal file
@@ -0,0 +1,68 @@
|
||||
# 🚀 Quick Start Guide
|
||||
|
||||
## Docker Deployment (Recommended)
|
||||
|
||||
### Prerequisites
|
||||
- Docker 20+ installed
|
||||
- Docker Compose installed
|
||||
|
||||
### Steps
|
||||
1. **Clone and setup**:
|
||||
```bash
|
||||
git clone https://github.com/hotheadhacker/seedbox-lite.git
|
||||
cd seedbox-lite
|
||||
```
|
||||
|
||||
2. **Configure environment** (optional):
|
||||
```bash
|
||||
# Edit .env file to change default password
|
||||
nano .env
|
||||
```
|
||||
|
||||
3. **Deploy**:
|
||||
```bash
|
||||
./deploy.sh docker
|
||||
```
|
||||
|
||||
4. **Access**:
|
||||
- Frontend: http://localhost:5174
|
||||
- Backend: http://localhost:3001
|
||||
- Default password: `seedbox123`
|
||||
|
||||
## PM2 Deployment
|
||||
|
||||
### Prerequisites
|
||||
- Node.js 18+ installed
|
||||
- PM2 installed globally (`npm install -g pm2`)
|
||||
|
||||
### Steps
|
||||
1. **Clone and setup**:
|
||||
```bash
|
||||
git clone https://github.com/hotheadhacker/seedbox-lite.git
|
||||
cd seedbox-lite
|
||||
```
|
||||
|
||||
2. **Deploy**:
|
||||
```bash
|
||||
./deploy.sh pm2
|
||||
```
|
||||
|
||||
3. **Access**:
|
||||
- Frontend: http://localhost:5174
|
||||
- Backend: http://localhost:3001
|
||||
|
||||
## Testing
|
||||
```bash
|
||||
# Test if everything is working
|
||||
./deploy.sh test
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
- **Port conflicts**: Edit `.env` file to change `FRONTEND_PORT` and `BACKEND_PORT`
|
||||
- **Docker issues**: Run `docker-compose down && docker-compose up --build`
|
||||
- **PM2 issues**: Run `pm2 kill && ./deploy.sh pm2`
|
||||
|
||||
## Security
|
||||
- Change `ACCESS_PASSWORD` in `.env` file immediately
|
||||
- Use HTTPS in production
|
||||
- Keep dependencies updated
|
||||
581
README.md
Normal file
581
README.md
Normal file
@@ -0,0 +1,581 @@
|
||||
# 🎬 SeedBox Lite - Stream Torrents Instantly
|
||||
|
||||
<div align="center">
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
**A modern, lightweight torrent streaming application with instant playback**
|
||||
|
||||
[Features](#-features) • [Screenshots](#-screenshots) • [Quick Start](#-quick-start) • [Installation](#-installation) • [Documentation](#-documentation)
|
||||
|
||||
</div>
|
||||
|
||||
## 🚀 Overview
|
||||
|
||||
SeedBox Lite is a cutting-edge torrent streaming platform that allows you to watch movies and TV shows instantly without waiting for complete downloads. Built with modern web technologies, it provides a Netflix-like experience with powerful torrent capabilities.
|
||||
|
||||
### ✨ Key Highlights
|
||||
|
||||
- **🎯 Instant Streaming** - Start watching immediately as the torrent downloads
|
||||
- **🔐 Password Protection** - Secure access with authentication
|
||||
- **📱 Mobile Optimized** - Perfect responsive design for all devices
|
||||
- **🎥 Smart Video Player** - Advanced player with subtitles and fullscreen support
|
||||
- **⚡ Fast Setup** - Deploy in minutes with Docker or PM2
|
||||
- **🌐 Cross-Platform** - Works on Windows, macOS, and Linux
|
||||
- **🎨 Modern UI** - Clean, intuitive interface inspired by popular streaming services
|
||||
|
||||
## 🎯 Features
|
||||
|
||||
### Core Streaming Features
|
||||
- **Torrent to Stream** - Convert any movie/TV torrent to instant streaming
|
||||
- **Progress Tracking** - Real-time download progress and cache management
|
||||
- **Smart Caching** - Intelligent caching system with configurable limits
|
||||
- **Multiple Formats** - Support for MP4, MKV, AVI, and more video formats
|
||||
- **Subtitle Support** - Automatic subtitle detection and loading
|
||||
|
||||
### User Experience
|
||||
- **Netflix-Style Interface** - Familiar and intuitive design
|
||||
- **Mobile-First Design** - Optimized for smartphones and tablets
|
||||
- **Native Fullscreen** - True fullscreen experience on mobile devices
|
||||
- **Gesture Controls** - Double-tap to fullscreen, intuitive video controls
|
||||
- **Responsive Layout** - Adapts perfectly to any screen size
|
||||
|
||||
### Technical Features
|
||||
- **Password Authentication** - Secure access control
|
||||
- **CORS Enabled** - Cross-origin resource sharing for flexible deployment
|
||||
- **Health Monitoring** - Built-in health checks and monitoring
|
||||
- **Production Ready** - Optimized for production deployments
|
||||
- **Docker Support** - Easy containerized deployment
|
||||
- **PM2 Integration** - Process management for Node.js applications
|
||||
|
||||
### Mobile Optimizations
|
||||
- **iOS Safari Support** - Native fullscreen using WebKit APIs
|
||||
- **Android Chrome** - Optimized for Android mobile browsers
|
||||
- **Range Requests** - HTTP range support for smooth video seeking
|
||||
- **Mobile Viewport** - Proper viewport handling for app-like experience
|
||||
- **Touch Optimized** - Gesture-friendly video controls
|
||||
|
||||
## 📸 Screenshots
|
||||
|
||||
### 🏠 Home Dashboard
|
||||
*Clean, modern interface showing available torrents and streaming options*
|
||||
|
||||
### 🔐 Login Screen
|
||||
*Secure authentication with Netflix-inspired design*
|
||||
|
||||
### 🎥 Video Player
|
||||
*Advanced video player with mobile-optimized controls and fullscreen support*
|
||||
|
||||
### 📱 Mobile Experience
|
||||
*Responsive design that works perfectly on all mobile devices*
|
||||
|
||||
### ⚙️ Settings Panel
|
||||
*Easy configuration and cache management interface*
|
||||
|
||||
## 🚀 Quick Start
|
||||
|
||||
### Using Docker (Recommended)
|
||||
|
||||
```bash
|
||||
# Clone the repository
|
||||
git clone https://github.com/hotheadhacker/seedbox-lite.git
|
||||
cd seedbox-lite
|
||||
|
||||
# Start with Docker Compose
|
||||
docker-compose up -d
|
||||
|
||||
# Access the application
|
||||
open http://localhost:5174
|
||||
```
|
||||
|
||||
### Using PM2
|
||||
|
||||
```bash
|
||||
# Clone and install dependencies
|
||||
git clone https://github.com/hotheadhacker/seedbox-lite.git
|
||||
cd seedbox-lite
|
||||
|
||||
# Install backend dependencies
|
||||
cd server-new && npm install
|
||||
|
||||
# Install frontend dependencies
|
||||
cd ../client && npm install
|
||||
|
||||
# Build frontend
|
||||
npm run build
|
||||
|
||||
# Start with PM2
|
||||
pm2 start ecosystem.config.js
|
||||
```
|
||||
|
||||
## 📋 Prerequisites
|
||||
|
||||
### System Requirements
|
||||
- **Node.js** 18+
|
||||
- **npm** 8+
|
||||
- **Docker** 20+ (for Docker deployment)
|
||||
- **PM2** (for PM2 deployment)
|
||||
|
||||
### Operating System Support
|
||||
- ✅ Windows 10/11
|
||||
- ✅ macOS 10.15+
|
||||
- ✅ Ubuntu 18.04+
|
||||
- ✅ Debian 10+
|
||||
- ✅ CentOS 7+
|
||||
|
||||
### Browser Support
|
||||
- ✅ Chrome 90+
|
||||
- ✅ Firefox 88+
|
||||
- ✅ Safari 14+
|
||||
- ✅ Edge 90+
|
||||
- ✅ Mobile browsers (iOS Safari, Android Chrome)
|
||||
|
||||
## 🛠 Installation
|
||||
|
||||
### Method 1: Docker Deployment (Recommended)
|
||||
|
||||
#### Step 1: Clone Repository
|
||||
```bash
|
||||
git clone https://github.com/hotheadhacker/seedbox-lite.git
|
||||
cd seedbox-lite
|
||||
```
|
||||
|
||||
#### Step 2: Configure Environment
|
||||
```bash
|
||||
# Copy and edit environment variables
|
||||
cp .env.example .env
|
||||
nano .env
|
||||
```
|
||||
|
||||
**Key Environment Variables:**
|
||||
```bash
|
||||
# Server Configuration
|
||||
NODE_ENV=production
|
||||
SERVER_PORT=3001
|
||||
ACCESS_PASSWORD=your_secure_password
|
||||
|
||||
# Frontend Configuration
|
||||
FRONTEND_URL=http://localhost:5174
|
||||
VITE_API_BASE_URL=http://localhost:3001
|
||||
|
||||
# Docker Ports
|
||||
BACKEND_PORT=3001
|
||||
FRONTEND_PORT=5174
|
||||
```
|
||||
|
||||
#### Step 3: Deploy
|
||||
```bash
|
||||
# Start all services
|
||||
docker-compose up -d
|
||||
|
||||
# Check status
|
||||
docker-compose ps
|
||||
|
||||
# View logs
|
||||
docker-compose logs -f
|
||||
```
|
||||
|
||||
#### Step 4: Access Application
|
||||
- **Frontend**: http://localhost:5174
|
||||
- **Backend API**: http://localhost:3001
|
||||
- **Default Login**: Password set in `ACCESS_PASSWORD`
|
||||
|
||||
### Method 2: PM2 Deployment
|
||||
|
||||
#### Step 1: System Setup
|
||||
```bash
|
||||
# Install Node.js 18+
|
||||
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
|
||||
sudo apt-get install -y nodejs
|
||||
|
||||
# Install PM2 globally
|
||||
npm install -g pm2
|
||||
```
|
||||
|
||||
#### Step 2: Application Setup
|
||||
```bash
|
||||
# Clone repository
|
||||
git clone https://github.com/hotheadhacker/seedbox-lite.git
|
||||
cd seedbox-lite
|
||||
|
||||
# Install backend dependencies
|
||||
cd server-new
|
||||
npm install
|
||||
cd ..
|
||||
|
||||
# Install and build frontend
|
||||
cd client
|
||||
npm install
|
||||
npm run build
|
||||
cd ..
|
||||
```
|
||||
|
||||
#### Step 3: Configure Environment
|
||||
```bash
|
||||
# Backend environment
|
||||
cd server-new
|
||||
cp .env.example .env
|
||||
nano .env
|
||||
```
|
||||
|
||||
**Backend `.env` Configuration:**
|
||||
```bash
|
||||
NODE_ENV=production
|
||||
SERVER_PORT=3001
|
||||
SERVER_HOST=0.0.0.0
|
||||
ACCESS_PASSWORD=your_secure_password
|
||||
FRONTEND_URL=http://localhost:5174
|
||||
```
|
||||
|
||||
#### Step 4: Start Services
|
||||
```bash
|
||||
# Start backend with PM2
|
||||
cd server-new
|
||||
pm2 start ecosystem.config.js
|
||||
|
||||
# Serve frontend with nginx or serve
|
||||
cd ../client/dist
|
||||
npx serve -s . -l 5174
|
||||
|
||||
# Or use PM2 for frontend
|
||||
pm2 start "npx serve -s . -l 5174" --name "seedbox-frontend"
|
||||
```
|
||||
|
||||
#### Step 5: PM2 Management
|
||||
```bash
|
||||
# View running processes
|
||||
pm2 list
|
||||
|
||||
# View logs
|
||||
pm2 logs
|
||||
|
||||
# Restart services
|
||||
pm2 restart all
|
||||
|
||||
# Save PM2 configuration
|
||||
pm2 save
|
||||
pm2 startup
|
||||
```
|
||||
|
||||
### Method 3: Development Setup
|
||||
|
||||
#### Step 1: Clone and Install
|
||||
```bash
|
||||
git clone https://github.com/hotheadhacker/seedbox-lite.git
|
||||
cd seedbox-lite
|
||||
|
||||
# Install backend dependencies
|
||||
cd server-new
|
||||
npm install
|
||||
|
||||
# Install frontend dependencies
|
||||
cd ../client
|
||||
npm install
|
||||
```
|
||||
|
||||
#### Step 2: Configure Development Environment
|
||||
```bash
|
||||
# Backend environment
|
||||
cd server-new
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
**Development `.env`:**
|
||||
```bash
|
||||
NODE_ENV=development
|
||||
SERVER_PORT=3000
|
||||
SERVER_HOST=localhost
|
||||
ACCESS_PASSWORD=seedbox123
|
||||
FRONTEND_URL=http://localhost:5173
|
||||
```
|
||||
|
||||
#### Step 3: Start Development Servers
|
||||
```bash
|
||||
# Terminal 1: Start backend
|
||||
cd server-new
|
||||
npm run dev
|
||||
|
||||
# Terminal 2: Start frontend
|
||||
cd client
|
||||
npm run dev
|
||||
```
|
||||
|
||||
## 🧪 Testing
|
||||
|
||||
### Docker Testing
|
||||
```bash
|
||||
# Health check
|
||||
curl http://localhost:3001/api/health
|
||||
curl http://localhost:5174/health
|
||||
|
||||
# API endpoints
|
||||
curl -X POST http://localhost:3001/api/auth/login \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"password":"your_password"}'
|
||||
|
||||
# Cache stats
|
||||
curl http://localhost:3001/api/cache/stats
|
||||
```
|
||||
|
||||
### PM2 Testing
|
||||
```bash
|
||||
# Check PM2 status
|
||||
pm2 list
|
||||
pm2 logs seedbox-backend
|
||||
pm2 logs seedbox-frontend
|
||||
|
||||
# Test API endpoints
|
||||
curl http://localhost:3001/api/health
|
||||
curl http://localhost:5174
|
||||
```
|
||||
|
||||
### Frontend Testing
|
||||
```bash
|
||||
cd client
|
||||
npm test
|
||||
|
||||
# Run Cypress e2e tests
|
||||
npm run test:e2e
|
||||
|
||||
# Accessibility testing
|
||||
npm run test:a11y
|
||||
```
|
||||
|
||||
### Backend Testing
|
||||
```bash
|
||||
cd server-new
|
||||
npm test
|
||||
|
||||
# API integration tests
|
||||
npm run test:integration
|
||||
|
||||
# Load testing
|
||||
npm run test:load
|
||||
```
|
||||
|
||||
## 📚 Configuration
|
||||
|
||||
### Environment Variables Reference
|
||||
|
||||
#### Backend Variables
|
||||
| Variable | Default | Description |
|
||||
|----------|---------|-------------|
|
||||
| `NODE_ENV` | `production` | Application environment |
|
||||
| `SERVER_PORT` | `3001` | Backend server port |
|
||||
| `SERVER_HOST` | `0.0.0.0` | Backend server host |
|
||||
| `ACCESS_PASSWORD` | `seedbox123` | Authentication password |
|
||||
| `MAX_CACHE_SIZE` | `5GB` | Maximum cache size |
|
||||
| `CLEANUP_INTERVAL` | `1h` | Cache cleanup interval |
|
||||
|
||||
#### Frontend Variables
|
||||
| Variable | Default | Description |
|
||||
|----------|---------|-------------|
|
||||
| `VITE_API_BASE_URL` | `http://localhost:3001` | Backend API URL |
|
||||
| `FRONTEND_URL` | `http://localhost:5174` | Frontend URL |
|
||||
|
||||
#### Docker Variables
|
||||
| Variable | Default | Description |
|
||||
|----------|---------|-------------|
|
||||
| `BACKEND_PORT` | `3001` | Docker backend port mapping |
|
||||
| `FRONTEND_PORT` | `5174` | Docker frontend port mapping |
|
||||
|
||||
### Advanced Configuration
|
||||
|
||||
#### Nginx Configuration (Production)
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name your-domain.com;
|
||||
|
||||
location / {
|
||||
proxy_pass http://localhost:5174;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
}
|
||||
|
||||
location /api/ {
|
||||
proxy_pass http://localhost:3001;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### SSL/HTTPS Setup
|
||||
```bash
|
||||
# Install Certbot
|
||||
sudo apt install certbot python3-certbot-nginx
|
||||
|
||||
# Get SSL certificate
|
||||
sudo certbot --nginx -d your-domain.com
|
||||
|
||||
# Auto-renewal
|
||||
sudo crontab -e
|
||||
# Add: 0 12 * * * /usr/bin/certbot renew --quiet
|
||||
```
|
||||
|
||||
## 🔧 Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
#### Port Conflicts
|
||||
```bash
|
||||
# Check if ports are in use
|
||||
lsof -i :3001
|
||||
lsof -i :5174
|
||||
|
||||
# Kill processes using ports
|
||||
sudo kill -9 $(lsof -ti:3001)
|
||||
sudo kill -9 $(lsof -ti:5174)
|
||||
```
|
||||
|
||||
#### Docker Issues
|
||||
```bash
|
||||
# Rebuild containers
|
||||
docker-compose down
|
||||
docker-compose up --build
|
||||
|
||||
# Clear Docker cache
|
||||
docker system prune -a
|
||||
|
||||
# Check container logs
|
||||
docker-compose logs seedbox-backend
|
||||
docker-compose logs seedbox-frontend
|
||||
```
|
||||
|
||||
#### PM2 Issues
|
||||
```bash
|
||||
# Reset PM2
|
||||
pm2 kill
|
||||
pm2 start ecosystem.config.js
|
||||
|
||||
# Check PM2 logs
|
||||
pm2 logs --lines 50
|
||||
|
||||
# Monitor PM2 processes
|
||||
pm2 monit
|
||||
```
|
||||
|
||||
#### Permission Issues
|
||||
```bash
|
||||
# Fix file permissions
|
||||
sudo chown -R $USER:$USER .
|
||||
chmod +x deploy.sh
|
||||
|
||||
# Docker permission issues
|
||||
sudo usermod -aG docker $USER
|
||||
newgrp docker
|
||||
```
|
||||
|
||||
#### Mobile Video Issues
|
||||
- Ensure CORS is enabled in backend
|
||||
- Check video format compatibility
|
||||
- Verify range request support
|
||||
- Test with different browsers
|
||||
|
||||
## 📖 API Documentation
|
||||
|
||||
### Authentication Endpoints
|
||||
```bash
|
||||
POST /api/auth/login
|
||||
{
|
||||
"password": "your_password"
|
||||
}
|
||||
```
|
||||
|
||||
### Torrent Endpoints
|
||||
```bash
|
||||
GET /api/torrents/search?q=movie+name
|
||||
POST /api/torrents/add
|
||||
{
|
||||
"magnetLink": "magnet:..."
|
||||
}
|
||||
```
|
||||
|
||||
### Streaming Endpoints
|
||||
```bash
|
||||
GET /api/stream/:torrentId/:fileIndex
|
||||
Range requests supported for video seeking
|
||||
```
|
||||
|
||||
### Cache Management
|
||||
```bash
|
||||
GET /api/cache/stats
|
||||
POST /api/cache/clear
|
||||
```
|
||||
|
||||
## 🛡 Security
|
||||
|
||||
### Best Practices
|
||||
- Change default password immediately
|
||||
- Use HTTPS in production
|
||||
- Keep dependencies updated
|
||||
- Enable firewall rules
|
||||
- Regular security audits
|
||||
|
||||
### Security Headers
|
||||
The application includes security headers:
|
||||
- X-Frame-Options: SAMEORIGIN
|
||||
- X-Content-Type-Options: nosniff
|
||||
- X-XSS-Protection: 1; mode=block
|
||||
- Referrer-Policy: no-referrer-when-downgrade
|
||||
|
||||
## 🚀 Deployment
|
||||
|
||||
### Production Deployment Checklist
|
||||
- [ ] Change default passwords
|
||||
- [ ] Configure HTTPS/SSL
|
||||
- [ ] Set up monitoring
|
||||
- [ ] Configure backups
|
||||
- [ ] Set up log rotation
|
||||
- [ ] Configure firewall
|
||||
- [ ] Test mobile compatibility
|
||||
- [ ] Verify video streaming
|
||||
- [ ] Test authentication
|
||||
- [ ] Monitor performance
|
||||
|
||||
### Scaling
|
||||
For high-traffic deployments:
|
||||
- Use load balancer (nginx/HAProxy)
|
||||
- Scale backend horizontally
|
||||
- Implement Redis for session storage
|
||||
- Use CDN for static assets
|
||||
- Monitor resource usage
|
||||
|
||||
## 📞 Support
|
||||
|
||||
### Getting Help
|
||||
- 📖 [Documentation](./docs/)
|
||||
- 🐛 [Issue Tracker](https://github.com/hotheadhacker/seedbox-lite/issues)
|
||||
- 💬 [Discussions](https://github.com/hotheadhacker/seedbox-lite/discussions)
|
||||
|
||||
### Contributing
|
||||
1. Fork the repository
|
||||
2. Create feature branch
|
||||
3. Make changes
|
||||
4. Add tests
|
||||
5. Submit pull request
|
||||
|
||||
## 📄 License
|
||||
|
||||
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
||||
|
||||
## 🙏 Acknowledgments
|
||||
|
||||
- WebTorrent for torrent streaming capabilities
|
||||
- React team for the amazing framework
|
||||
- Docker community for containerization
|
||||
- All contributors and users
|
||||
|
||||
---
|
||||
|
||||
<div align="center">
|
||||
|
||||
**Made with ❤️ by [hotheadhacker](https://github.com/hotheadhacker)**
|
||||
|
||||
⭐ Star this repo if you find it useful!
|
||||
|
||||
</div>
|
||||
53
client/.dockerignore
Normal file
53
client/.dockerignore
Normal file
@@ -0,0 +1,53 @@
|
||||
# Docker ignore patterns for frontend
|
||||
node_modules
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Build output
|
||||
dist/
|
||||
build/
|
||||
|
||||
# Environment files (except production)
|
||||
.env
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
!.env.production
|
||||
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage/
|
||||
*.lcov
|
||||
|
||||
# IDE files
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# OS files
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Git
|
||||
.git
|
||||
.gitignore
|
||||
|
||||
# Docker files
|
||||
Dockerfile*
|
||||
docker-compose*
|
||||
.dockerignore
|
||||
|
||||
# Cache directories
|
||||
.cache/
|
||||
.parcel-cache/
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
@@ -1,2 +1,10 @@
|
||||
# Production Environment Variables
|
||||
# Production Environment Variables for Docker deployment
|
||||
VITE_API_BASE_URL=https://seedbox-api.isalman.dev
|
||||
|
||||
# App configuration
|
||||
VITE_APP_NAME=SeedBox Lite
|
||||
VITE_APP_VERSION=1.0.0
|
||||
|
||||
# Feature flags
|
||||
VITE_ENABLE_PWA=true
|
||||
VITE_ENABLE_ANALYTICS=false
|
||||
|
||||
59
client/Dockerfile
Normal file
59
client/Dockerfile
Normal file
@@ -0,0 +1,59 @@
|
||||
# Multi-stage build for React frontend
|
||||
FROM node:18-alpine AS builder
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /app
|
||||
|
||||
# Copy package files
|
||||
COPY package*.json ./
|
||||
|
||||
# Install dependencies
|
||||
RUN npm ci && npm cache clean --force
|
||||
|
||||
# Copy source code
|
||||
COPY . .
|
||||
|
||||
# Build arguments
|
||||
ARG VITE_API_BASE_URL=http://localhost:3001
|
||||
ENV VITE_API_BASE_URL=$VITE_API_BASE_URL
|
||||
|
||||
# Build the application
|
||||
RUN npm run build
|
||||
|
||||
# Production stage with nginx
|
||||
FROM nginx:alpine AS production
|
||||
|
||||
# Install curl for healthcheck
|
||||
RUN apk add --no-cache curl
|
||||
|
||||
# Copy custom nginx config
|
||||
COPY nginx.conf /etc/nginx/nginx.conf
|
||||
|
||||
# Copy built app from builder stage
|
||||
COPY --from=builder /app/dist /usr/share/nginx/html
|
||||
|
||||
# Create nginx user
|
||||
RUN adduser -D -s /bin/sh nginx || true
|
||||
|
||||
# Set proper permissions
|
||||
RUN chown -R nginx:nginx /usr/share/nginx/html && \
|
||||
chown -R nginx:nginx /var/cache/nginx && \
|
||||
chown -R nginx:nginx /var/log/nginx && \
|
||||
chown -R nginx:nginx /etc/nginx/conf.d
|
||||
|
||||
# Make nginx run as non-root
|
||||
RUN touch /var/run/nginx.pid && \
|
||||
chown -R nginx:nginx /var/run/nginx.pid
|
||||
|
||||
# Switch to nginx user
|
||||
USER nginx
|
||||
|
||||
# Expose port 80
|
||||
EXPOSE 80
|
||||
|
||||
# Health check
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=10s --retries=3 \
|
||||
CMD curl -f http://localhost:80 || exit 1
|
||||
|
||||
# Start nginx
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
22
client/Dockerfile.dev
Normal file
22
client/Dockerfile.dev
Normal file
@@ -0,0 +1,22 @@
|
||||
# Development Dockerfile for hot reload
|
||||
FROM node:18-alpine
|
||||
|
||||
# Install curl for healthcheck
|
||||
RUN apk add --no-cache curl
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy package files
|
||||
COPY package*.json ./
|
||||
|
||||
# Install all dependencies (including dev)
|
||||
RUN npm install
|
||||
|
||||
# Copy source code
|
||||
COPY . .
|
||||
|
||||
# Expose port
|
||||
EXPOSE 5174
|
||||
|
||||
# Start development server
|
||||
CMD ["npm", "run", "dev", "--", "--host", "0.0.0.0"]
|
||||
92
client/nginx.conf
Normal file
92
client/nginx.conf
Normal file
@@ -0,0 +1,92 @@
|
||||
user nginx;
|
||||
worker_processes auto;
|
||||
pid /var/run/nginx.pid;
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
use epoll;
|
||||
multi_accept on;
|
||||
}
|
||||
|
||||
http {
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
# Logging
|
||||
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||
|
||||
access_log /var/log/nginx/access.log main;
|
||||
error_log /var/log/nginx/error.log warn;
|
||||
|
||||
# Basic settings
|
||||
sendfile on;
|
||||
tcp_nopush on;
|
||||
tcp_nodelay on;
|
||||
keepalive_timeout 65;
|
||||
types_hash_max_size 2048;
|
||||
client_max_body_size 16M;
|
||||
|
||||
# Gzip compression
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_min_length 1024;
|
||||
gzip_proxied any;
|
||||
gzip_comp_level 6;
|
||||
gzip_types
|
||||
text/plain
|
||||
text/css
|
||||
text/xml
|
||||
text/javascript
|
||||
application/json
|
||||
application/javascript
|
||||
application/xml+rss
|
||||
application/atom+xml
|
||||
image/svg+xml;
|
||||
|
||||
# Security headers
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-XSS-Protection "1; mode=block" always;
|
||||
add_header Referrer-Policy "no-referrer-when-downgrade" always;
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
|
||||
root /usr/share/nginx/html;
|
||||
index index.html index.htm;
|
||||
|
||||
# Static file caching
|
||||
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
try_files $uri =404;
|
||||
}
|
||||
|
||||
# Handle React router
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
|
||||
# Security headers for HTML
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-XSS-Protection "1; mode=block" always;
|
||||
}
|
||||
|
||||
# Health check endpoint
|
||||
location /health {
|
||||
access_log off;
|
||||
return 200 "healthy\n";
|
||||
add_header Content-Type text/plain;
|
||||
}
|
||||
|
||||
# Disable access to hidden files
|
||||
location ~ /\. {
|
||||
deny all;
|
||||
access_log off;
|
||||
log_not_found off;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -49,9 +49,12 @@ const AuthenticatedApp = () => {
|
||||
return (
|
||||
<Router>
|
||||
<Routes>
|
||||
{/* Full-width Netflix-style page without sidebar */}
|
||||
<Route path="torrent/:torrentHash" element={<TorrentPageNetflix />} />
|
||||
|
||||
{/* Main app with sidebar layout */}
|
||||
<Route path="/" element={<Layout />}>
|
||||
<Route index element={<HomePage />} />
|
||||
<Route path="torrent/:torrentHash" element={<TorrentPageNetflix />} />
|
||||
<Route path="recent" element={<RecentPage />} />
|
||||
<Route path="settings" element={<SettingsPage />} />
|
||||
<Route path="cache" element={<CacheManagementPage />} />
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
.cache-page {
|
||||
padding: 24px;
|
||||
padding: 24px 24px 24px 0; /* Remove left padding since main-content has padding now */
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
min-height: 100vh;
|
||||
@@ -405,7 +405,7 @@
|
||||
/* Mobile Responsiveness */
|
||||
@media (max-width: 768px) {
|
||||
.cache-page {
|
||||
padding: 16px;
|
||||
padding: 16px 0; /* Remove horizontal padding on mobile since main-content handles it */
|
||||
}
|
||||
|
||||
.page-header {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
.home-page {
|
||||
padding: 20px 40px; /* Reduced top/bottom padding, keep left/right */
|
||||
padding: 20px 40px 20px 20px; /* Reduced left padding since main-content has padding now */
|
||||
max-width: 1000px;
|
||||
margin: 0; /* Remove auto centering to prevent left alignment */
|
||||
background: #0a0a0a;
|
||||
@@ -598,7 +598,7 @@
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.home-page {
|
||||
padding: 16px;
|
||||
padding: 16px 0; /* Remove horizontal padding on mobile since main-content handles it */
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -318,12 +318,14 @@
|
||||
min-height: 100vh;
|
||||
overflow-x: hidden;
|
||||
width: 100%;
|
||||
margin-left: 300px; /* Account for sidebar width + spacing */
|
||||
margin-left: 280px; /* Account for sidebar width */
|
||||
padding-left: 20px; /* Add padding for visual spacing */
|
||||
}
|
||||
|
||||
/* When sidebar is collapsed, main content expands */
|
||||
.main-content.expanded {
|
||||
margin-left: 100px; /* Account for collapsed sidebar width + spacing */
|
||||
margin-left: 80px; /* Account for collapsed sidebar width */
|
||||
padding-left: 20px; /* Maintain consistent padding */
|
||||
}
|
||||
|
||||
/* Mobile Overlay */
|
||||
@@ -388,12 +390,13 @@
|
||||
.main-content {
|
||||
margin-top: 56px;
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
padding: 0 16px; /* Add mobile padding */
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.main-content.expanded {
|
||||
margin-left: 0;
|
||||
padding: 0 16px; /* Maintain mobile padding */
|
||||
}
|
||||
|
||||
.mobile-overlay {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
.recent-page {
|
||||
padding: 24px;
|
||||
padding: 24px 24px 24px 0; /* Remove left padding since main-content has padding now */
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
@@ -292,7 +292,7 @@
|
||||
/* Responsive */
|
||||
@media (max-width: 768px) {
|
||||
.recent-page {
|
||||
padding: 16px;
|
||||
padding: 16px 0; /* Remove horizontal padding on mobile since main-content handles it */
|
||||
}
|
||||
|
||||
.page-header {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
.settings-page {
|
||||
padding: 24px;
|
||||
padding: 24px 24px 24px 0; /* Remove left padding since main-content has padding now */
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
@@ -383,7 +383,7 @@ input:disabled + .slider:hover {
|
||||
/* Mobile Responsive Design */
|
||||
@media (max-width: 768px) {
|
||||
.settings-page {
|
||||
padding: 16px 12px;
|
||||
padding: 16px 0; /* Remove horizontal padding on mobile since main-content handles it */
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
.torrent-page {
|
||||
padding: 24px;
|
||||
padding: 24px 24px 24px 0; /* Remove left padding since main-content has padding now */
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
@@ -260,12 +260,13 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0; /* Remove any default padding that might cause sizing issues */
|
||||
}
|
||||
|
||||
/* Mobile Responsive */
|
||||
@media (max-width: 768px) {
|
||||
.torrent-page {
|
||||
padding: 16px;
|
||||
padding: 16px 0; /* Remove horizontal padding on mobile since main-content handles it */
|
||||
}
|
||||
|
||||
.torrent-header {
|
||||
@@ -290,6 +291,12 @@
|
||||
.play-button {
|
||||
align-self: flex-start;
|
||||
}
|
||||
|
||||
/* Fix video overlay mobile responsiveness */
|
||||
.video-overlay {
|
||||
padding: 0 !important; /* Ensure no padding on mobile */
|
||||
margin: 0 !important; /* Ensure no margin on mobile */
|
||||
}
|
||||
}
|
||||
|
||||
/* Enhanced UI styles */
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
/* Netflix-style Torrent Page Styles */
|
||||
.netflix-page {
|
||||
width: 100vw;
|
||||
min-height: 100vh;
|
||||
background: #141414;
|
||||
color: #ffffff;
|
||||
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
/* Loading State */
|
||||
@@ -71,16 +75,19 @@
|
||||
background: #f40612;
|
||||
}
|
||||
|
||||
/* Hero Section */
|
||||
/* Hero Section */
|
||||
.netflix-hero {
|
||||
height: 80vh;
|
||||
position: relative;
|
||||
height: 60vh;
|
||||
background: linear-gradient(rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.7));
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
padding: 0 60px;
|
||||
align-items: flex-end;
|
||||
width: 100%;
|
||||
padding: 40px;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.netflix-hero-content {
|
||||
@@ -95,7 +102,7 @@
|
||||
.netflix-back-btn {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
left: 20px;
|
||||
left: 40px; /* Align with hero padding */
|
||||
background: rgba(42, 42, 42, 0.8);
|
||||
color: white;
|
||||
border: none;
|
||||
@@ -240,9 +247,9 @@
|
||||
.netflix-content {
|
||||
display: flex;
|
||||
gap: 40px;
|
||||
padding: 40px 60px;
|
||||
max-width: 1400px;
|
||||
margin: 0 auto;
|
||||
padding: 0; /* No padding since netflix-page handles it */
|
||||
max-width: none; /* Use full available width */
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.netflix-main-content {
|
||||
@@ -567,7 +574,12 @@
|
||||
@media (max-width: 1024px) {
|
||||
.netflix-hero {
|
||||
height: 70vh;
|
||||
padding: 0 40px;
|
||||
margin: -24px -24px 24px 0; /* Maintain breakout */
|
||||
padding: 40px; /* Consistent padding */
|
||||
}
|
||||
|
||||
.netflix-back-btn {
|
||||
left: 40px; /* Align with hero padding */
|
||||
}
|
||||
|
||||
.netflix-hero-content {
|
||||
@@ -592,7 +604,7 @@
|
||||
|
||||
.netflix-content {
|
||||
flex-direction: column;
|
||||
padding: 30px 40px;
|
||||
padding: 0; /* No additional padding */
|
||||
}
|
||||
|
||||
.netflix-sidebar {
|
||||
@@ -601,9 +613,18 @@
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.netflix-page {
|
||||
padding: 16px 16px 16px 0; /* Mobile padding like other pages */
|
||||
}
|
||||
|
||||
.netflix-hero {
|
||||
height: 60vh;
|
||||
padding: 0 20px;
|
||||
margin: -16px -16px 16px 0; /* Adjust for mobile padding */
|
||||
padding: 20px; /* Mobile padding */
|
||||
}
|
||||
|
||||
.netflix-back-btn {
|
||||
left: 20px; /* Mobile position */
|
||||
}
|
||||
|
||||
.netflix-title {
|
||||
@@ -621,7 +642,7 @@
|
||||
}
|
||||
|
||||
.netflix-content {
|
||||
padding: 20px;
|
||||
padding: 0; /* No additional padding */
|
||||
}
|
||||
|
||||
.netflix-episode {
|
||||
@@ -654,7 +675,7 @@
|
||||
@media (max-width: 480px) {
|
||||
.netflix-back-btn {
|
||||
top: 10px;
|
||||
left: 10px;
|
||||
left: 10px; /* Standard small mobile position */
|
||||
padding: 8px 12px;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
@@ -682,3 +703,27 @@
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* Video Overlay - consistent with TorrentPage */
|
||||
.video-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.95);
|
||||
z-index: 1000;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0; /* Remove any default padding that might cause sizing issues */
|
||||
margin: 0; /* Ensure no margin interference */
|
||||
}
|
||||
|
||||
/* Mobile video overlay fixes */
|
||||
@media (max-width: 768px) {
|
||||
.video-overlay {
|
||||
padding: 0 !important; /* Force remove padding on mobile */
|
||||
margin: 0 !important; /* Force remove margin on mobile */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,19 +178,21 @@ const TorrentPageNetflix = () => {
|
||||
console.log('🎬 Video selected:', selectedVideo.name, 'Resume from:', initialProgress + 's');
|
||||
|
||||
return (
|
||||
<VideoPlayer
|
||||
key={videoKey}
|
||||
src={`${config.apiBaseUrl}/api/torrents/${torrentHash}/files/${selectedVideo.index}/stream`}
|
||||
title={selectedVideo.name}
|
||||
onClose={() => setSelectedVideo(null)}
|
||||
onTimeUpdate={() => {
|
||||
// The VideoPlayer itself handles saving progress with correct duration
|
||||
// We don't need to save it here since VideoPlayer saves every 5 seconds
|
||||
}}
|
||||
initialTime={initialProgress}
|
||||
torrentHash={torrentHash}
|
||||
fileIndex={selectedVideo.index}
|
||||
/>
|
||||
<div className="video-overlay">
|
||||
<VideoPlayer
|
||||
key={videoKey}
|
||||
src={`${config.apiBaseUrl}/api/torrents/${torrentHash}/files/${selectedVideo.index}/stream`}
|
||||
title={selectedVideo.name}
|
||||
onClose={() => setSelectedVideo(null)}
|
||||
onTimeUpdate={() => {
|
||||
// The VideoPlayer itself handles saving progress with correct duration
|
||||
// We don't need to save it here since VideoPlayer saves every 5 seconds
|
||||
}}
|
||||
initialTime={initialProgress}
|
||||
torrentHash={torrentHash}
|
||||
fileIndex={selectedVideo.index}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -988,12 +988,16 @@
|
||||
height: 100vh !important;
|
||||
z-index: 9999 !important;
|
||||
border-radius: 0 !important;
|
||||
margin: 0 !important; /* Remove any margin */
|
||||
padding: 0 !important; /* Remove any padding */
|
||||
}
|
||||
|
||||
.video-player-container.fullscreen .video-element {
|
||||
width: 100vw !important;
|
||||
height: 100vh !important;
|
||||
object-fit: contain !important;
|
||||
margin: 0 !important; /* Remove any margin */
|
||||
padding: 0 !important; /* Remove any padding */
|
||||
}
|
||||
|
||||
/* Ensure controls are visible in mobile fullscreen */
|
||||
@@ -1002,6 +1006,25 @@
|
||||
bottom: 0 !important;
|
||||
left: 0 !important;
|
||||
right: 0 !important;
|
||||
margin: 0 !important; /* Remove any margin that might cause bottom space */
|
||||
}
|
||||
|
||||
/* Fix non-fullscreen mobile video player sizing */
|
||||
.video-player-container:not(.fullscreen) {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
max-width: 100% !important;
|
||||
max-height: 100% !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.video-player-container:not(.fullscreen) .video-element {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
object-fit: contain !important;
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
/* Enhanced fullscreen button for mobile */
|
||||
|
||||
319
deploy.sh
Executable file
319
deploy.sh
Executable file
@@ -0,0 +1,319 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 🚀 SeedBox Lite Deployment Script
|
||||
# Simple deployment script for Docker and PM2
|
||||
|
||||
set -e
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
PURPLE='\033[0;35m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Default values
|
||||
MODE=${1:-help}
|
||||
ENV_FILE=".env"
|
||||
|
||||
# Helper functions
|
||||
print_header() {
|
||||
echo -e "\n${PURPLE}================================${NC}"
|
||||
echo -e "${PURPLE}🎬 SeedBox Lite Deployment${NC}"
|
||||
echo -e "${PURPLE}================================${NC}\n"
|
||||
}
|
||||
|
||||
print_success() {
|
||||
echo -e "${GREEN}✓${NC} $1"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}⚠${NC} $1"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}✗${NC} $1"
|
||||
}
|
||||
|
||||
print_info() {
|
||||
echo -e "${BLUE}ℹ${NC} $1"
|
||||
}
|
||||
|
||||
# Check if .env file exists
|
||||
check_env() {
|
||||
if [ ! -f "$ENV_FILE" ]; then
|
||||
print_warning ".env file not found. Using existing one..."
|
||||
fi
|
||||
print_success ".env file found"
|
||||
}
|
||||
|
||||
# Docker deployment
|
||||
deploy_docker() {
|
||||
print_header
|
||||
print_info "Starting Docker deployment..."
|
||||
|
||||
# Check if Docker is running
|
||||
if ! docker info > /dev/null 2>&1; then
|
||||
print_error "Docker is not running. Please start Docker and try again."
|
||||
exit 1
|
||||
fi
|
||||
print_success "Docker is running"
|
||||
|
||||
# Check if docker-compose is available
|
||||
if ! command -v docker-compose &> /dev/null; then
|
||||
print_error "Docker Compose is not installed."
|
||||
exit 1
|
||||
fi
|
||||
print_success "Docker Compose is available"
|
||||
|
||||
# Check .env file
|
||||
check_env
|
||||
|
||||
# Stop existing containers
|
||||
print_info "Stopping existing containers..."
|
||||
docker-compose down 2>/dev/null || true
|
||||
|
||||
# Build and start containers
|
||||
print_info "Building and starting containers..."
|
||||
docker-compose up --build -d
|
||||
|
||||
# Wait for containers to start
|
||||
print_info "Waiting for containers to start..."
|
||||
sleep 10
|
||||
|
||||
# Check container status
|
||||
print_info "Checking container status..."
|
||||
if docker-compose ps | grep -q "Up"; then
|
||||
print_success "Containers are running"
|
||||
|
||||
# Display access URLs
|
||||
echo -e "\n${GREEN}🌐 Access URLs:${NC}"
|
||||
echo -e "Frontend: ${BLUE}http://localhost:$(grep FRONTEND_PORT .env | cut -d'=' -f2 2>/dev/null || echo 5174)${NC}"
|
||||
echo -e "Backend: ${BLUE}http://localhost:$(grep BACKEND_PORT .env | cut -d'=' -f2 2>/dev/null || echo 3001)${NC}"
|
||||
echo -e "Password: ${YELLOW}$(grep ACCESS_PASSWORD .env | cut -d'=' -f2 2>/dev/null || echo seedbox123)${NC}"
|
||||
|
||||
# Show useful commands
|
||||
echo -e "\n${BLUE}🛠 Useful commands:${NC}"
|
||||
echo " View logs: docker-compose logs -f"
|
||||
echo " Stop services: docker-compose down"
|
||||
echo " Restart: docker-compose restart"
|
||||
echo " Update: ./deploy.sh docker"
|
||||
|
||||
else
|
||||
print_error "Some containers failed to start"
|
||||
docker-compose logs
|
||||
exit 1
|
||||
}
|
||||
|
||||
# PM2 deployment
|
||||
deploy_pm2() {
|
||||
print_header
|
||||
print_info "Starting PM2 deployment..."
|
||||
|
||||
# Check if PM2 is installed
|
||||
if ! command -v pm2 &> /dev/null; then
|
||||
print_warning "PM2 is not installed. Installing..."
|
||||
npm install -g pm2
|
||||
fi
|
||||
print_success "PM2 is available"
|
||||
|
||||
# Check Node.js version
|
||||
NODE_VERSION=$(node -v | cut -d'v' -f2 | cut -d'.' -f1)
|
||||
if [ "$NODE_VERSION" -lt 18 ]; then
|
||||
print_error "Node.js 18+ is required. Current version: $(node -v)"
|
||||
exit 1
|
||||
fi
|
||||
print_success "Node.js version is compatible"
|
||||
|
||||
# Check .env file
|
||||
check_env
|
||||
|
||||
# Install backend dependencies
|
||||
print_info "Installing backend dependencies..."
|
||||
cd server-new
|
||||
npm install --production
|
||||
cd ..
|
||||
print_success "Backend dependencies installed"
|
||||
|
||||
# Install and build frontend
|
||||
print_info "Installing and building frontend..."
|
||||
cd client
|
||||
npm install
|
||||
npm run build
|
||||
cd ..
|
||||
print_success "Frontend built successfully"
|
||||
|
||||
# Create PM2 ecosystem file if it doesn't exist
|
||||
if [ ! -f "ecosystem.config.js" ]; then
|
||||
print_info "Creating PM2 ecosystem configuration..."
|
||||
cat > ecosystem.config.js << 'EOF'
|
||||
module.exports = {
|
||||
apps: [
|
||||
{
|
||||
name: 'seedbox-backend',
|
||||
script: 'index.js',
|
||||
cwd: './server-new',
|
||||
env: {
|
||||
NODE_ENV: 'production',
|
||||
},
|
||||
env_file: '../.env',
|
||||
instances: 1,
|
||||
exec_mode: 'cluster',
|
||||
watch: false,
|
||||
max_memory_restart: '1G',
|
||||
error_file: './logs/err.log',
|
||||
out_file: './logs/out.log',
|
||||
log_file: './logs/combined.log',
|
||||
time: true
|
||||
},
|
||||
{
|
||||
name: 'seedbox-frontend',
|
||||
script: 'serve',
|
||||
args: '-s dist -l 5174',
|
||||
cwd: './client',
|
||||
instances: 1,
|
||||
exec_mode: 'cluster',
|
||||
watch: false,
|
||||
env: {
|
||||
NODE_ENV: 'production'
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
EOF
|
||||
print_success "Created PM2 ecosystem configuration"
|
||||
fi
|
||||
|
||||
# Create logs directory
|
||||
mkdir -p server-new/logs
|
||||
|
||||
# Stop existing PM2 processes
|
||||
print_info "Stopping existing PM2 processes..."
|
||||
pm2 delete seedbox-backend 2>/dev/null || true
|
||||
pm2 delete seedbox-frontend 2>/dev/null || true
|
||||
|
||||
# Install serve for frontend if not installed
|
||||
if ! command -v serve &> /dev/null; then
|
||||
print_info "Installing serve for frontend..."
|
||||
npm install -g serve
|
||||
fi
|
||||
|
||||
# Start PM2 processes
|
||||
print_info "Starting PM2 processes..."
|
||||
pm2 start ecosystem.config.js
|
||||
|
||||
# Save PM2 configuration
|
||||
pm2 save
|
||||
|
||||
# Check process status
|
||||
if pm2 list | grep -q "online"; then
|
||||
print_success "PM2 processes are running"
|
||||
|
||||
# Display access URLs
|
||||
echo -e "\n${GREEN}🌐 Access URLs:${NC}"
|
||||
echo -e "Frontend: ${BLUE}http://localhost:$(grep FRONTEND_PORT .env | cut -d'=' -f2 2>/dev/null || echo 5174)${NC}"
|
||||
echo -e "Backend: ${BLUE}http://localhost:$(grep BACKEND_PORT .env | cut -d'=' -f2 2>/dev/null || echo 3001)${NC}"
|
||||
echo -e "Password: ${YELLOW}$(grep ACCESS_PASSWORD .env | cut -d'=' -f2 2>/dev/null || echo seedbox123)${NC}"
|
||||
|
||||
# Show PM2 commands
|
||||
echo -e "\n${BLUE}<EFBFBD> PM2 commands:${NC}"
|
||||
echo " View processes: pm2 list"
|
||||
echo " View logs: pm2 logs"
|
||||
echo " Restart: pm2 restart all"
|
||||
echo " Stop: pm2 stop all"
|
||||
echo " Monitor: pm2 monit"
|
||||
|
||||
else
|
||||
print_error "PM2 processes failed to start"
|
||||
pm2 logs
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Test deployment
|
||||
test_deployment() {
|
||||
print_header
|
||||
print_info "Testing deployment..."
|
||||
|
||||
# Load environment variables
|
||||
if [ -f .env ]; then
|
||||
export $(cat .env | grep -v '^#' | xargs)
|
||||
fi
|
||||
|
||||
BACKEND_URL="http://localhost:${BACKEND_PORT:-3001}"
|
||||
FRONTEND_URL="http://localhost:${FRONTEND_PORT:-5174}"
|
||||
|
||||
print_info "Testing backend health..."
|
||||
if curl -f -s "${BACKEND_URL}/api/health" > /dev/null; then
|
||||
print_success "Backend is healthy"
|
||||
else
|
||||
print_error "Backend health check failed"
|
||||
return 1
|
||||
fi
|
||||
|
||||
print_info "Testing frontend..."
|
||||
if curl -f -s "${FRONTEND_URL}" > /dev/null; then
|
||||
print_success "Frontend is accessible"
|
||||
else
|
||||
print_error "Frontend is not accessible"
|
||||
return 1
|
||||
fi
|
||||
|
||||
print_info "Testing authentication..."
|
||||
AUTH_RESPONSE=$(curl -s -X POST "${BACKEND_URL}/api/auth/login" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"password\":\"${ACCESS_PASSWORD}\"}")
|
||||
|
||||
if echo "$AUTH_RESPONSE" | grep -q "token"; then
|
||||
print_success "Authentication is working"
|
||||
else
|
||||
print_warning "Authentication test inconclusive"
|
||||
fi
|
||||
|
||||
print_success "All tests passed!"
|
||||
}
|
||||
|
||||
# Show help
|
||||
show_help() {
|
||||
print_header
|
||||
echo -e "${BLUE}Usage:${NC}"
|
||||
echo " ./deploy.sh docker - Deploy using Docker Compose"
|
||||
echo " ./deploy.sh pm2 - Deploy using PM2"
|
||||
echo " ./deploy.sh test - Test current deployment"
|
||||
echo " ./deploy.sh help - Show this help"
|
||||
echo ""
|
||||
echo -e "${BLUE}Requirements:${NC}"
|
||||
echo " Docker: Docker 20+ and Docker Compose"
|
||||
echo " PM2: Node.js 18+ and PM2"
|
||||
echo ""
|
||||
echo -e "${BLUE}Configuration:${NC}"
|
||||
echo " Edit .env file to customize settings"
|
||||
echo " Change ACCESS_PASSWORD for security"
|
||||
echo ""
|
||||
echo -e "${BLUE}Examples:${NC}"
|
||||
echo " ./deploy.sh docker # Quick Docker deployment"
|
||||
echo " ./deploy.sh pm2 # Production PM2 deployment"
|
||||
echo " ./deploy.sh test # Test if everything works"
|
||||
}
|
||||
|
||||
# Main script logic
|
||||
case $MODE in
|
||||
docker)
|
||||
deploy_docker
|
||||
;;
|
||||
pm2)
|
||||
deploy_pm2
|
||||
;;
|
||||
test)
|
||||
test_deployment
|
||||
;;
|
||||
help|--help|-h)
|
||||
show_help
|
||||
;;
|
||||
*)
|
||||
print_error "Unknown command: $MODE"
|
||||
show_help
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
28
docker-compose.prod.yml
Normal file
28
docker-compose.prod.yml
Normal file
@@ -0,0 +1,28 @@
|
||||
# Production Docker Compose configuration
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
seedbox-backend:
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
- SERVER_PORT=3001
|
||||
- SERVER_HOST=0.0.0.0
|
||||
- FRONTEND_URL=https://<domain>
|
||||
- ACCESS_PASSWORD=${ACCESS_PASSWORD:-sadsgasgdkjh}
|
||||
env_file:
|
||||
- ./server-new/.env.docker
|
||||
|
||||
seedbox-frontend:
|
||||
build:
|
||||
args:
|
||||
- VITE_API_BASE_URL=https://apidomain.com
|
||||
env_file:
|
||||
- ./client/.env.production
|
||||
|
||||
# Enable nginx for production
|
||||
nginx:
|
||||
profiles:
|
||||
- production
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
44
docker-compose.yml
Normal file
44
docker-compose.yml
Normal file
@@ -0,0 +1,44 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
# Backend API Server
|
||||
seedbox-backend:
|
||||
build:
|
||||
context: ./server-new
|
||||
dockerfile: Dockerfile
|
||||
container_name: seedbox-backend
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "${BACKEND_PORT:-3001}:3001"
|
||||
env_file:
|
||||
- .env
|
||||
volumes:
|
||||
- seedbox_data:/app/data
|
||||
- seedbox_cache:/app/cache
|
||||
networks:
|
||||
- seedbox-network
|
||||
|
||||
# Frontend Web Server
|
||||
seedbox-frontend:
|
||||
build:
|
||||
context: ./client
|
||||
dockerfile: Dockerfile
|
||||
args:
|
||||
- VITE_API_BASE_URL=${VITE_API_BASE_URL:-http://localhost:3001}
|
||||
container_name: seedbox-frontend
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "${FRONTEND_PORT:-5174}:80"
|
||||
depends_on:
|
||||
- seedbox-backend
|
||||
networks:
|
||||
- seedbox-network
|
||||
volumes:
|
||||
seedbox_data:
|
||||
driver: local
|
||||
seedbox_cache:
|
||||
driver: local
|
||||
|
||||
networks:
|
||||
seedbox-network:
|
||||
driver: bridge
|
||||
40
ecosystem.config.js
Normal file
40
ecosystem.config.js
Normal file
@@ -0,0 +1,40 @@
|
||||
module.exports = {
|
||||
apps: [
|
||||
{
|
||||
name: 'seedbox-backend',
|
||||
script: 'index.js',
|
||||
cwd: './server-new',
|
||||
env: {
|
||||
NODE_ENV: 'production',
|
||||
},
|
||||
env_file: '../.env',
|
||||
instances: 1,
|
||||
exec_mode: 'cluster',
|
||||
watch: false,
|
||||
max_memory_restart: '1G',
|
||||
error_file: './logs/err.log',
|
||||
out_file: './logs/out.log',
|
||||
log_file: './logs/combined.log',
|
||||
time: true,
|
||||
restart_delay: 1000,
|
||||
max_restarts: 10,
|
||||
min_uptime: '10s'
|
||||
},
|
||||
{
|
||||
name: 'seedbox-frontend',
|
||||
script: 'serve',
|
||||
args: '-s dist -l 5174 -n',
|
||||
cwd: './client',
|
||||
instances: 1,
|
||||
exec_mode: 'cluster',
|
||||
watch: false,
|
||||
max_memory_restart: '512M',
|
||||
env: {
|
||||
NODE_ENV: 'production'
|
||||
},
|
||||
restart_delay: 1000,
|
||||
max_restarts: 10,
|
||||
min_uptime: '10s'
|
||||
}
|
||||
]
|
||||
};
|
||||
108
nginx/nginx.conf
Normal file
108
nginx/nginx.conf
Normal file
@@ -0,0 +1,108 @@
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
upstream backend {
|
||||
server seedbox-backend:3001;
|
||||
}
|
||||
|
||||
upstream frontend {
|
||||
server seedbox-frontend:80;
|
||||
}
|
||||
|
||||
# Rate limiting
|
||||
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
|
||||
limit_req_zone $binary_remote_addr zone=download:10m rate=5r/s;
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name seedbox.isalman.dev;
|
||||
|
||||
# Security headers
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-XSS-Protection "1; mode=block" always;
|
||||
add_header Referrer-Policy "no-referrer-when-downgrade" always;
|
||||
|
||||
# Frontend routes
|
||||
location / {
|
||||
proxy_pass http://frontend;
|
||||
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;
|
||||
}
|
||||
|
||||
# API routes
|
||||
location /api/ {
|
||||
limit_req zone=api burst=20 nodelay;
|
||||
|
||||
proxy_pass http://backend;
|
||||
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;
|
||||
|
||||
# CORS headers
|
||||
add_header Access-Control-Allow-Origin "*" always;
|
||||
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
|
||||
add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization" always;
|
||||
add_header Access-Control-Expose-Headers "Content-Length,Content-Range" always;
|
||||
|
||||
# Handle preflight requests
|
||||
if ($request_method = 'OPTIONS') {
|
||||
add_header Access-Control-Allow-Origin "*";
|
||||
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS";
|
||||
add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization";
|
||||
add_header Content-Type text/plain;
|
||||
add_header Content-Length 0;
|
||||
return 204;
|
||||
}
|
||||
}
|
||||
|
||||
# Video streaming with rate limiting
|
||||
location /api/stream/ {
|
||||
limit_req zone=download burst=10 nodelay;
|
||||
|
||||
proxy_pass http://backend;
|
||||
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_set_header Range $http_range;
|
||||
|
||||
# Streaming optimizations
|
||||
proxy_buffering off;
|
||||
proxy_cache off;
|
||||
proxy_read_timeout 300s;
|
||||
proxy_connect_timeout 30s;
|
||||
proxy_send_timeout 300s;
|
||||
|
||||
# Allow large file streaming
|
||||
client_max_body_size 0;
|
||||
proxy_max_temp_file_size 0;
|
||||
}
|
||||
|
||||
# Health check
|
||||
location /health {
|
||||
access_log off;
|
||||
return 200 "healthy\n";
|
||||
add_header Content-Type text/plain;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Additional server block for HTTPS (when SSL certificates are available)
|
||||
# server {
|
||||
# listen 443 ssl http2;
|
||||
# server_name seedbox.isalman.dev;
|
||||
#
|
||||
# ssl_certificate /etc/nginx/ssl/seedbox.crt;
|
||||
# ssl_certificate_key /etc/nginx/ssl/seedbox.key;
|
||||
# ssl_protocols TLSv1.2 TLSv1.3;
|
||||
# ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
|
||||
# ssl_prefer_server_ciphers off;
|
||||
#
|
||||
# # Same location blocks as above
|
||||
# }
|
||||
59
server-new/.dockerignore
Normal file
59
server-new/.dockerignore
Normal file
@@ -0,0 +1,59 @@
|
||||
# Docker ignore patterns for backend
|
||||
node_modules
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
.nyc_output
|
||||
coverage
|
||||
|
||||
# Environment files (except docker env)
|
||||
.env
|
||||
.env.local
|
||||
.env.*.local
|
||||
!.env.docker
|
||||
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# Cache and temp directories
|
||||
cache/
|
||||
tmp/
|
||||
temp/
|
||||
|
||||
# IDE files
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# OS files
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Git
|
||||
.git
|
||||
.gitignore
|
||||
|
||||
# Docker files
|
||||
Dockerfile*
|
||||
docker-compose*
|
||||
.dockerignore
|
||||
21
server-new/.env.docker
Normal file
21
server-new/.env.docker
Normal file
@@ -0,0 +1,21 @@
|
||||
# Environment variables for Docker production deployment
|
||||
NODE_ENV=production
|
||||
SERVER_PORT=3001
|
||||
SERVER_HOST=0.0.0.0
|
||||
FRONTEND_URL=https://seedbox.isalman.dev
|
||||
OMDB_API_KEY=trilogy
|
||||
ACCESS_PASSWORD=seedbox123
|
||||
|
||||
# Cache and data directories
|
||||
CACHE_DIR=/app/cache
|
||||
DATA_DIR=/app/data
|
||||
LOG_DIR=/app/logs
|
||||
|
||||
# Performance settings
|
||||
MAX_CACHE_SIZE=5368709120
|
||||
CLEANUP_INTERVAL=3600000
|
||||
TORRENT_TIMEOUT=30000
|
||||
|
||||
# Security settings
|
||||
ENABLE_CORS=true
|
||||
TRUST_PROXY=true
|
||||
51
server-new/Dockerfile
Normal file
51
server-new/Dockerfile
Normal file
@@ -0,0 +1,51 @@
|
||||
# Multi-stage build for production
|
||||
FROM node:18-alpine AS builder
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /app
|
||||
|
||||
# Copy package files
|
||||
COPY package*.json ./
|
||||
|
||||
# Install dependencies
|
||||
RUN npm ci --only=production && npm cache clean --force
|
||||
|
||||
# Copy source code
|
||||
COPY . .
|
||||
|
||||
# Remove unnecessary files
|
||||
RUN rm -rf node_modules/.cache
|
||||
|
||||
# Production stage
|
||||
FROM node:18-alpine AS production
|
||||
|
||||
# Install curl for healthcheck
|
||||
RUN apk add --no-cache curl
|
||||
|
||||
# Create app user
|
||||
RUN addgroup -g 1001 -S nodejs
|
||||
RUN adduser -S nodejs -u 1001
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /app
|
||||
|
||||
# Copy node_modules and app from builder stage
|
||||
COPY --from=builder --chown=nodejs:nodejs /app/node_modules ./node_modules
|
||||
COPY --from=builder --chown=nodejs:nodejs /app/package*.json ./
|
||||
COPY --chown=nodejs:nodejs . .
|
||||
|
||||
# Create directories for data and cache
|
||||
RUN mkdir -p /app/data /app/cache /app/logs && chown -R nodejs:nodejs /app
|
||||
|
||||
# Switch to non-root user
|
||||
USER nodejs
|
||||
|
||||
# Expose port
|
||||
EXPOSE 3001
|
||||
|
||||
# Health check
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
|
||||
CMD curl -f http://localhost:3001/api/health || exit 1
|
||||
|
||||
# Start the application
|
||||
CMD ["node", "index.js"]
|
||||
1420
server-new/index.js
1420
server-new/index.js
File diff suppressed because it is too large
Load Diff
@@ -1,17 +0,0 @@
|
||||
{
|
||||
"name": "seedbox-lite-server",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"start": "node index.js",
|
||||
"dev": "NODE_ENV=development node index.js",
|
||||
"prod": "NODE_ENV=production node index.js",
|
||||
"start:docker": "cp .env.docker .env && node index.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"cors": "2.8.5",
|
||||
"dotenv": "^17.2.1",
|
||||
"express": "4.18.2",
|
||||
"multer": "^2.0.2",
|
||||
"webtorrent": "^1.9.7"
|
||||
}
|
||||
}
|
||||
21
server/.env.docker
Normal file
21
server/.env.docker
Normal file
@@ -0,0 +1,21 @@
|
||||
# Environment variables for Docker production deployment
|
||||
NODE_ENV=production
|
||||
SERVER_PORT=3001
|
||||
SERVER_HOST=0.0.0.0
|
||||
FRONTEND_URL=https://seedbox.isalman.dev
|
||||
OMDB_API_KEY=trilogy
|
||||
ACCESS_PASSWORD=seedbox123
|
||||
|
||||
# Cache and data directories
|
||||
CACHE_DIR=/app/cache
|
||||
DATA_DIR=/app/data
|
||||
LOG_DIR=/app/logs
|
||||
|
||||
# Performance settings
|
||||
MAX_CACHE_SIZE=5368709120
|
||||
CLEANUP_INTERVAL=3600000
|
||||
TORRENT_TIMEOUT=30000
|
||||
|
||||
# Security settings
|
||||
ENABLE_CORS=true
|
||||
TRUST_PROXY=true
|
||||
7
server/.env.production
Normal file
7
server/.env.production
Normal file
@@ -0,0 +1,7 @@
|
||||
SERVER_PORT=3001
|
||||
SERVER_HOST=0.0.0.0
|
||||
FRONTEND_URL=https://seedbox.isalman.dev
|
||||
VITE_API_BASE_URL=https://seedbox-api.isalman.dev
|
||||
OMDB_API_KEY=trilogy
|
||||
ACCESS_PASSWORD=seedbox123
|
||||
NODE_ENV=production
|
||||
51
server/Dockerfile
Normal file
51
server/Dockerfile
Normal file
@@ -0,0 +1,51 @@
|
||||
# Multi-stage build for production
|
||||
FROM node:18-alpine AS builder
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /app
|
||||
|
||||
# Copy package files
|
||||
COPY package*.json ./
|
||||
|
||||
# Install dependencies
|
||||
RUN npm ci --only=production && npm cache clean --force
|
||||
|
||||
# Copy source code
|
||||
COPY . .
|
||||
|
||||
# Remove unnecessary files
|
||||
RUN rm -rf node_modules/.cache
|
||||
|
||||
# Production stage
|
||||
FROM node:18-alpine AS production
|
||||
|
||||
# Install curl for healthcheck
|
||||
RUN apk add --no-cache curl
|
||||
|
||||
# Create app user
|
||||
RUN addgroup -g 1001 -S nodejs
|
||||
RUN adduser -S nodejs -u 1001
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /app
|
||||
|
||||
# Copy node_modules and app from builder stage
|
||||
COPY --from=builder --chown=nodejs:nodejs /app/node_modules ./node_modules
|
||||
COPY --from=builder --chown=nodejs:nodejs /app/package*.json ./
|
||||
COPY --chown=nodejs:nodejs . .
|
||||
|
||||
# Create directories for data and cache
|
||||
RUN mkdir -p /app/data /app/cache /app/logs && chown -R nodejs:nodejs /app
|
||||
|
||||
# Switch to non-root user
|
||||
USER nodejs
|
||||
|
||||
# Expose port
|
||||
EXPOSE 3001
|
||||
|
||||
# Health check
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
|
||||
CMD curl -f http://localhost:3001/api/health || exit 1
|
||||
|
||||
# Start the application
|
||||
CMD ["node", "index.js"]
|
||||
1420
server/index.js
1420
server/index.js
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "seedbox-lite-server",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"start": "node index.js",
|
||||
"dev": "NODE_ENV=development node index.js",
|
||||
"prod": "NODE_ENV=production node index.js",
|
||||
"start:docker": "cp .env.docker .env && node index.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"cors": "2.8.5",
|
||||
"dotenv": "^17.2.1",
|
||||
"express": "4.18.2",
|
||||
"multer": "^2.0.2",
|
||||
"webtorrent": "^1.9.7"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user