feat: Add complete Docker deployment with web-based setup wizard

Major additions:
- Web-based setup wizard (setup.php, setup_wizard.php, setup-wizard.js)
- Production Docker configuration (docker-compose.prod.yml, .env.production)
- Database initialization SQL files (deploy/init_settings.sql)
- Template builder system with drag-and-drop UI
- Advanced features (OAuth, CDN, enhanced analytics, monetization)
- Comprehensive documentation (deployment guides, quick start, feature docs)
- Design system with accessibility and responsive layout
- Deployment automation scripts (deploy.ps1, generate-secrets.ps1)

Setup wizard allows customization of:
- Platform name and branding
- Domain configuration
- Membership tiers and pricing
- Admin credentials
- Feature toggles

Database includes 270+ tables for complete video streaming platform with
advanced features for analytics, moderation, template building, and monetization.

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
SamiAhmed7777
2025-10-26 01:42:31 -07:00
parent 0b7e2d0a5b
commit d22b3e1c0d
90 changed files with 22329 additions and 268 deletions

365
docker-compose.prod.yml Normal file
View File

@@ -0,0 +1,365 @@
version: "3.8"
# ============================================================================
# EasyStream - Production Docker Compose Configuration
# ============================================================================
# Usage: docker-compose -f docker-compose.prod.yml up -d
#
# IMPORTANT: Before deployment:
# 1. Copy .env.production to .env and fill in all values
# 2. Generate secure secrets for all services
# 3. Set up SSL/TLS certificates
# 4. Configure external volumes for data persistence
# 5. Set up monitoring and logging
# ============================================================================
services:
db:
image: mariadb:10.6
container_name: easystream-db-prod
restart: always
environment:
MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_password
MYSQL_DATABASE: ${DB_NAME:-easystream}
MYSQL_USER: ${DB_USER:-easystream}
MYSQL_PASSWORD_FILE: /run/secrets/db_password
ports:
- "127.0.0.1:3306:3306" # Only bind to localhost
volumes:
- db_data:/var/lib/mysql
- ./__install/easystream.sql:/docker-entrypoint-initdb.d/1-main_schema.sql:ro
- ./__install/add_advanced_features.sql:/docker-entrypoint-initdb.d/2-advanced_features.sql:ro
- ./deploy/init_settings.sql:/docker-entrypoint-initdb.d/3-init_settings.sql:ro
- ./deploy/backup:/backup # For database backups
secrets:
- db_root_password
- db_password
healthcheck:
test: ["CMD-SHELL", "mysqladmin ping -h 127.0.0.1 -u ${DB_USER:-easystream} --silent || exit 1"]
start_period: 120s
interval: 30s
timeout: 10s
retries: 5
networks:
- backend
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
php:
build:
context: .
dockerfile: Dockerfile.php
args:
PHP_VERSION: 8.2
image: easystream-php:production
container_name: easystream-php-prod
restart: always
working_dir: /srv/easystream
environment:
TZ: ${TZ:-UTC}
DB_HOST: db
DB_NAME: ${DB_NAME:-easystream}
DB_USER: ${DB_USER:-easystream}
DB_PASS_FILE: /run/secrets/db_password
REDIS_HOST: redis
REDIS_PORT: 6379
REDIS_DB: 0
MAIN_URL: ${MAIN_URL}
DEBUG: "false"
APP_ENV: production
PHP_MEMORY_LIMIT: 512M
PHP_UPLOAD_MAX_FILESIZE: 256M
PHP_POST_MAX_SIZE: 256M
volumes:
- ./:/srv/easystream:ro # Read-only for security
- app_uploads:/srv/easystream/f_data/uploads
- app_cache:/srv/easystream/f_data/cache
- app_logs:/srv/easystream/f_data/logs
- rtmp_hls:/var/www/hls:ro
- rtmp_rec:/mnt/rec:ro
secrets:
- db_password
- api_key
- jwt_secret
- encryption_key
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
networks:
- frontend
- backend
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "5"
caddy:
image: caddy:2-alpine
container_name: easystream-caddy-prod
restart: always
depends_on:
php:
condition: service_started
srs:
condition: service_started
ports:
- "80:80"
- "443:443"
- "443:443/udp" # HTTP/3
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- ./:/srv/easystream:ro
- rtmp_hls:/var/www/hls:ro
- caddy_data:/data
- caddy_config:/config
- ./deploy/ssl:/ssl:ro # For custom SSL certificates
networks:
- frontend
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:80/health"]
interval: 30s
timeout: 10s
retries: 3
srs:
image: ossrs/srs:5
container_name: easystream-srs-prod
restart: always
ports:
- "1935:1935" # RTMP ingest
- "1985:1985" # HTTP API
- "8080:8080" # HTTP Server
volumes:
- ./deploy/srs.conf:/usr/local/srs/conf/srs.conf:ro
- rtmp_hls:/srs/hls
- rtmp_rec:/srs/rec
- srs_logs:/usr/local/srs/objs/logs
command: ["/usr/local/srs/objs/srs", "-c", "/usr/local/srs/conf/srs.conf"]
networks:
- frontend
- backend
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
redis:
image: redis:7-alpine
container_name: easystream-redis-prod
restart: always
ports:
- "127.0.0.1:6379:6379" # Only bind to localhost
volumes:
- redis_data:/data
command: >
redis-server
--appendonly yes
--maxmemory 512mb
--maxmemory-policy allkeys-lru
--requirepass ${REDIS_PASSWORD:-}
--save 900 1
--save 300 10
--save 60 10000
networks:
- backend
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 30s
timeout: 10s
retries: 5
logging:
driver: "json-file"
options:
max-size: "5m"
max-file: "3"
cron:
build:
context: .
dockerfile: Dockerfile.cron
image: easystream-cron:production
container_name: easystream-cron-prod
restart: always
depends_on:
php:
condition: service_started
environment:
TZ: ${TZ:-UTC}
DB_HOST: db
DB_NAME: ${DB_NAME:-easystream}
DB_USER: ${DB_USER:-easystream}
DB_PASS_FILE: /run/secrets/db_password
CRON_BASE_URL: ${MAIN_URL}
CRON_SSK_FILE: /run/secrets/cron_secret
VOD_REC_PATH: /mnt/rec
REDIS_HOST: redis
REDIS_PORT: 6379
REDIS_DB: 0
volumes:
- ./:/srv/easystream:ro
- rtmp_rec:/mnt/rec:ro
- cron_logs:/var/log/cron
secrets:
- db_password
- cron_secret
networks:
- backend
logging:
driver: "json-file"
options:
max-size: "5m"
max-file: "3"
queue-worker:
build:
context: .
dockerfile: Dockerfile.php
image: easystream-php:production
container_name: easystream-worker-prod
restart: always
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
environment:
TZ: ${TZ:-UTC}
DB_HOST: db
DB_NAME: ${DB_NAME:-easystream}
DB_USER: ${DB_USER:-easystream}
DB_PASS_FILE: /run/secrets/db_password
REDIS_HOST: redis
REDIS_PORT: 6379
WORKER_QUEUES: ${WORKER_QUEUES:-default,video,email,notifications}
WORKER_SLEEP: ${WORKER_SLEEP:-3}
WORKER_TIMEOUT: ${WORKER_TIMEOUT:-300}
volumes:
- ./:/srv/easystream:ro
- app_uploads:/srv/easystream/f_data/uploads
- rtmp_hls:/var/www/hls
- rtmp_rec:/mnt/rec
secrets:
- db_password
command: php f_scripts/queue_worker.php
networks:
- backend
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "5"
deploy:
replicas: 2 # Run 2 workers for high availability
abr:
image: jrottenberg/ffmpeg:5.1-ubuntu
container_name: easystream-abr-prod
restart: always
entrypoint: ["/bin/bash"]
command: ["/abr.sh"]
depends_on:
srs:
condition: service_started
environment:
ABR_STREAM_KEY: ${ABR_STREAM_KEY:-}
volumes:
- rtmp_hls:/var/www/hls
- ./deploy/abr.sh:/abr.sh:ro
networks:
- backend
logging:
driver: "json-file"
options:
max-size: "5m"
max-file: "3"
# ============================================================================
# Docker Secrets (Production Security)
# ============================================================================
# Create these files before deployment:
# echo "your_secret" | docker secret create db_root_password -
# echo "your_secret" | docker secret create db_password -
# etc.
# ============================================================================
secrets:
db_root_password:
file: ./secrets/db_root_password.txt
db_password:
file: ./secrets/db_password.txt
api_key:
file: ./secrets/api_key.txt
jwt_secret:
file: ./secrets/jwt_secret.txt
encryption_key:
file: ./secrets/encryption_key.txt
cron_secret:
file: ./secrets/cron_secret.txt
# ============================================================================
# Persistent Volumes
# ============================================================================
volumes:
db_data:
driver: local
driver_opts:
type: none
o: bind
device: /var/lib/easystream/db
redis_data:
driver: local
app_uploads:
driver: local
driver_opts:
type: none
o: bind
device: /var/lib/easystream/uploads
app_cache:
driver: local
app_logs:
driver: local
driver_opts:
type: none
o: bind
device: /var/log/easystream
rtmp_hls:
driver: local
rtmp_rec:
driver: local
driver_opts:
type: none
o: bind
device: /var/lib/easystream/recordings
srs_logs:
driver: local
cron_logs:
driver: local
caddy_data:
driver: local
caddy_config:
driver: local
# ============================================================================
# Networks
# ============================================================================
networks:
frontend:
driver: bridge
backend:
driver: bridge
internal: true # Backend network not accessible from outside