Platform Installation & Deployment Guide
Complete technical documentation for deploying, configuring, and maintaining the EscenarioAI browser-based DAW platform. Intended for system administrators and licensees.
Platform Overview
EscenarioAI is an AI-powered browser-based Digital Audio Workstation (DAW) and track mixer. It enables musicians, producers, and audio engineers to upload, separate, process, and mix audio tracks entirely in the browser, powered by server-side AI models for stem separation, voice cloning, text-to-instrument synthesis, and intelligent VST parameter mapping.
System Architecture
Technology Stack
| Layer | Technology | Version | Purpose |
|---|---|---|---|
| Frontend (Studio) | React + Vite + Zustand | 19 / 8 / 5 | Browser-based DAW interface |
| Audio Engine | Web Audio API + AudioWorklets | - | Real-time audio processing |
| Backend API | FastAPI + Uvicorn | 0.115 / 0.30 | REST API + WebSocket server |
| Task Queue | Celery + Redis | 5.4 / 7 | Async audio processing jobs |
| Database | PostgreSQL + SQLAlchemy | 16 / 2.0 | Persistent data storage (async) |
| VST Hosting | Carla + Wine64 + Pedalboard | - | Plugin loading & audio routing |
| AI Services | OpenAI API | 1.82 | Chat, VST parameter mapping |
| Cloud Storage | Cloudflare R2 (S3-compatible) | - | Audio file persistence |
| GPU Compute | RunPod / Modal | - | Demucs stem separation, RVC |
| Reverse Proxy | Nginx + Certbot | - | SSL termination, routing |
| Containerization | Docker + Docker Compose | 24+ / v2 | Service orchestration |
| i18n | i18next | 26 | 7 languages (EN, ES, FR, PT, IT, JA, HI) |
Server Requirements
Hardware Specifications
| Resource | Minimum | Recommended |
|---|---|---|
| CPU | 4 vCPU | 8 vCPU (dedicated cores) |
| RAM | 8 GB | 16 GB |
| Storage | 100 GB SSD | 250 GB NVMe SSD |
| Bandwidth | 1 Gbps | 1 Gbps unmetered |
| OS | Ubuntu 22.04 LTS (required) | |
Note: Audio processing (stem separation, mastering) is CPU-intensive. With GPU offloading (RunPod/Modal), the minimum spec is sufficient. Without GPU, the recommended spec is strongly advised for concurrent users.
Network Ports
| Port | Protocol | Access | Service |
|---|---|---|---|
80 | TCP | Public | HTTP (Nginx, redirects to 443) |
443 | TCP | Public | HTTPS (Nginx + Certbot SSL) |
22 | TCP | Admin only | SSH access |
8000 | TCP | localhost only | FastAPI backend (Docker) |
5432 | TCP | Docker internal | PostgreSQL |
6379 | TCP | Docker internal | Redis |
9090 | TCP | Docker internal | VST Host (Carla) |
Domain Requirements
Four DNS A records pointing to your server IP:
| Subdomain | Purpose | Content Served |
|---|---|---|
yourdomain.com | Landing page | Static marketing site |
studio.yourdomain.com | DAW application | React frontend + API proxy |
editor.yourdomain.com | Legacy editor | Separate audio editor build |
admin.yourdomain.com | Admin panel | Management dashboard + API proxy |
Prerequisites Installation
All commands assume a fresh Ubuntu 22.04 LTS server with root access.
System Update
apt update && apt upgrade -y apt install -y curl wget git unzip software-properties-common
Docker Engine 24+
# Remove old Docker versions apt remove -y docker docker-engine docker.io containerd runc 2>/dev/null # Add Docker official GPG key and repository install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc chmod a+r /etc/apt/keyrings/docker.asc echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] \ https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" \ | tee /etc/apt/sources.list.d/docker.list > /dev/null # Install Docker Engine + Compose apt update apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin # Verify installation docker --version docker compose version
Node.js 20+ (via nvm)
# Install nvm curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash source ~/.bashrc # Install Node.js 20 LTS nvm install 20 nvm use 20 nvm alias default 20 # Verify node --version # v20.x.x npm --version
Nginx
apt install -y nginx systemctl enable nginx systemctl start nginx
Certbot (SSL)
apt install -y certbot python3-certbot-nginx
Firewall Configuration
ufw allow OpenSSH ufw allow 'Nginx Full' ufw --force enable ufw status
Backend Deployment
Clone Repository
mkdir -p /opt/escenario cd /opt/escenario git clone https://github.com/YOUR_ORG/escenario-backend.git backend cd backend
Directory Structure
Environment Configuration
Create the .env file in the backend root directory:
# ============================================ # EscenarioAI Backend Configuration # ============================================ # --- Database (PostgreSQL) --- DATABASE_URL=postgresql+asyncpg://escenario:YOUR_DB_PASSWORD@db:5432/escenario_db DATABASE_URL_SYNC=postgresql://escenario:YOUR_DB_PASSWORD@db:5432/escenario_db # --- Redis --- REDIS_URL=redis://redis:6379/0 # --- Authentication --- SECRET_KEY=GENERATE_A_64_CHAR_RANDOM_STRING_HERE ALGORITHM=HS256 ACCESS_TOKEN_EXPIRE_MINUTES=1440 # --- Cloud Storage (Cloudflare R2) --- R2_ENDPOINT_URL=https://YOUR_ACCOUNT_ID.r2.cloudflarestorage.com R2_ACCESS_KEY_ID=YOUR_R2_ACCESS_KEY R2_SECRET_ACCESS_KEY=YOUR_R2_SECRET_KEY R2_BUCKET_NAME=escenario-audio # --- GPU Processing (Optional) --- RUNPOD_API_KEY= RUNPOD_ENDPOINT_ID= MODAL_WEBHOOK_URL= # --- AI Services --- OPENAI_API_KEY=sk-YOUR_OPENAI_API_KEY # --- CORS (comma-separated origins) --- ALLOWED_ORIGINS=https://yourdomain.com,https://studio.yourdomain.com,https://editor.yourdomain.com,https://admin.yourdomain.com,http://localhost:5173 # --- Upload Limits --- MAX_UPLOAD_SIZE_MB=100 MAX_VST_UPLOAD_SIZE_MB=500 # --- VST Host --- VST_HOST_URL=http://vst-host:9090
Security: Generate SECRET_KEY with: python3 -c "import secrets; print(secrets.token_urlsafe(48))"
Docker Compose Services
The platform runs as 5 interconnected Docker services:
1. PostgreSQL Database (db)
PostgreSQL 16 Alpine with persistent volume. Auto-creates the escenario_db database. Health check ensures the service is ready before dependents start.
2. Redis (redis)
Redis 7 Alpine for Celery task brokering, WebSocket pub/sub, and session caching. No persistence configured (ephemeral cache).
3. Backend (backend)
Python 3.11-slim running FastAPI via Uvicorn with 4 workers. Binds to 127.0.0.1:8000 (not public). Mounts workspace volume for audio files, host Docker socket for auto-updater functionality.
4. Celery Worker (celery-worker)
Same Docker image as backend, runs Celery with --concurrency=2 on the default queue. Handles all async audio processing: stem separation, effects, mastering, VST operations.
5. VST Host (vst-host)
Ubuntu 22.04 with Wine64 (Windows VST bridging), Carla (headless plugin rack), and audio libraries. Exposes port 9090 internally for the backend to communicate with.
Launch the Platform
cd /opt/escenario/backend # Build and start all services docker compose up -d --build # Monitor build progress docker compose logs -f # Verify all services are healthy docker compose ps # Test API health endpoint curl http://localhost:8000/health
Expected response: {"status": "healthy", "version": "1.0.0", "service": "EscenarioAI"}
Create Admin User
# Enter the backend container docker compose exec backend bash # Generate password hash python3 -c "from passlib.context import CryptContext; \ pwd = CryptContext(schemes=['bcrypt']); \ print(pwd.hash('YOUR_ADMIN_PASSWORD'))" # Insert admin user via psql docker compose exec db psql -U escenario -d escenario_db -c \ "INSERT INTO users (email, full_name, hashed_password, plan, is_active, is_admin) \ VALUES ('admin@yourdomain.com', 'Admin', 'PASTE_HASH_HERE', 'PRO', true, true);"
Frontend Deployment
Studio DAW (Primary Application)
The main DAW interface built with React 19, Vite 8, and Zustand 5.
# Clone the frontend repository cd /opt/escenario git clone https://github.com/YOUR_ORG/escenario-frontend.git frontend cd frontend # Ensure Node 20 is active source ~/.nvm/nvm.sh && nvm use 20 # Install dependencies npm install # Update API proxy in vite.config.js to point to your server # (only needed for local dev; production uses Nginx proxy) # Build for production npm run build # Deploy build output mkdir -p /var/www/escenario/frontend cp -r dist/* /var/www/escenario/frontend/
Key Frontend Components
| Component | File | Purpose |
|---|---|---|
| Main DAW | Studio.jsx | Multi-track timeline, transport, mixing (75KB) |
| Audio Engine | AudioEngine.js | Web Audio graph, routing, effects chain (27KB) |
| VST Panel | VSTPluginPanel.jsx | Plugin upload, parameter control, AI mapping |
| Collaboration | CollabPanel.jsx | Real-time rooms via WebSocket |
| Mixer | MixerPanel.jsx | Channel strips, faders, routing |
| Mastering | MasteringPanel.jsx | Multi-band processing, presets, export |
| AI Chat | AiChat.jsx | OpenAI-powered production assistant |
| Vocal Recorder | VocalRecorder.jsx | Browser recording with MP3 encoding |
Dependencies
| Package | Version | Purpose |
|---|---|---|
react | 19.2 | UI framework |
zustand | 5.0 | State management (stores) |
axios | 1.16 | HTTP client for API calls |
react-router-dom | 7.15 | Client-side routing |
i18next | 26.2 | Internationalization (7 languages) |
lamejs | 1.2 | Client-side MP3 encoding |
Editor (Legacy Audio Editor)
# Clone and build the editor cd /opt/escenario git clone https://github.com/YOUR_ORG/escenario-editor.git editor cd editor # Build (if applicable) or copy directly mkdir -p /var/www/escenario/editor cp -r ./* /var/www/escenario/editor/
Admin Panel
A static HTML single-page application with no build step required.
mkdir -p /var/www/escenario/admin
# Deploy the admin panel HTML file
cp /opt/escenario/admin-panel/index.html /var/www/escenario/admin/
Admin panel features: User management (create/edit/deactivate), platform analytics, VST plugin oversight, system health monitoring, GPU queue status, auto-updater, documentation, and support portal link.
Landing Page
mkdir -p /var/www/escenario/landing
# Deploy landing page files
cp /opt/escenario/escenario-landing/* /var/www/escenario/landing/
Includes: index.html, terms.html, privacy.html, dmca.html, refund.html, logo assets.
Nginx Configuration
Studio Subdomain (Primary DAW)
# /etc/nginx/sites-available/studio-escenario server { listen 80; server_name studio.yourdomain.com; client_max_body_size 150M; root /var/www/escenario/frontend; index index.html; # API proxy location /api/ { proxy_pass http://127.0.0.1:8000/api/; 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_read_timeout 300s; proxy_connect_timeout 10s; } # WebSocket for collaboration location /ws/ { proxy_pass http://127.0.0.1:8000/ws/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_read_timeout 86400; } # Static file serving (audio workspace) location /static/ { proxy_pass http://127.0.0.1:8000/static/; proxy_set_header Host $host; } # Health check passthrough location /health { proxy_pass http://127.0.0.1:8000/health; } # SPA fallback location / { try_files $uri $uri/ /index.html; } # Compression gzip on; gzip_types text/plain text/css application/json application/javascript text/xml application/xml text/javascript audio/wav audio/mpeg; gzip_min_length 1000; }
Admin Subdomain
# /etc/nginx/sites-available/admin-escenario
server {
listen 80;
server_name admin.yourdomain.com;
root /var/www/escenario/admin;
index index.html;
location /api/ {
proxy_pass http://127.0.0.1:8000/api/;
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_read_timeout 300s;
}
location / {
try_files $uri $uri/ /index.html;
}
}
Editor Subdomain
# /etc/nginx/sites-available/editor-escenario
server {
listen 80;
server_name editor.yourdomain.com;
root /var/www/escenario/editor;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
gzip on;
gzip_types text/plain text/css application/json application/javascript;
}
Landing Page (Root Domain)
# /etc/nginx/sites-available/landing-escenario
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
root /var/www/escenario/landing;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
Enable Sites & SSL
# Enable all sites ln -sf /etc/nginx/sites-available/studio-escenario /etc/nginx/sites-enabled/ ln -sf /etc/nginx/sites-available/admin-escenario /etc/nginx/sites-enabled/ ln -sf /etc/nginx/sites-available/editor-escenario /etc/nginx/sites-enabled/ ln -sf /etc/nginx/sites-available/landing-escenario /etc/nginx/sites-enabled/ # Remove default site rm -f /etc/nginx/sites-enabled/default # Test configuration nginx -t # Reload Nginx systemctl reload nginx # Issue SSL certificates for all domains certbot --nginx \ -d yourdomain.com \ -d www.yourdomain.com \ -d studio.yourdomain.com \ -d editor.yourdomain.com \ -d admin.yourdomain.com \ --non-interactive --agree-tos -m admin@yourdomain.com # Verify auto-renewal certbot renew --dry-run
Database Schema
All tables are auto-created by SQLAlchemy on first startup via Base.metadata.create_all(). No manual migrations required for fresh deployments.
users
projects
tracks
audio_tasks
vst_plugins
collaboration_rooms
room_participants
room_messages
Enum Storage: PostgreSQL stores enum member names (uppercase: FREE, PRO, ENTERPRISE), not values. This is SQLAlchemy's default behavior with PostgreSQL Enum types.
API Reference
All endpoints are prefixed with /api/v1. Protected routes require a JWT Bearer token in the Authorization header.
Authentication
Projects & Tracks
Audio Processing
File Upload
AI Chat
VST Plugin Management ENTERPRISE
Admin Panel ADMIN ONLY
Real-Time Collaboration
Authentication: Include Authorization: Bearer <token> header on all protected routes. Tokens expire after 24 hours (configurable via ACCESS_TOKEN_EXPIRE_MINUTES).
Cloud Storage (Cloudflare R2)
EscenarioAI uses Cloudflare R2 (S3-compatible) for persistent audio file storage. This is optional for development but recommended for production.
Setup Steps
- Log in to Cloudflare Dashboard → R2 Object Storage
- Create a bucket named
escenario-audio - Go to Manage R2 API Tokens → Create token with read/write permissions
- Note your Account ID (visible in the dashboard URL)
Environment Variables
R2_ENDPOINT_URL=https://YOUR_ACCOUNT_ID.r2.cloudflarestorage.com R2_ACCESS_KEY_ID=your_access_key_id R2_SECRET_ACCESS_KEY=your_secret_access_key R2_BUCKET_NAME=escenario-audio
File Organization
Local Storage Fallback
If R2 is not configured (empty environment variables), the platform falls back to local filesystem storage at /var/workspace/ inside the Docker volume. This works for development and single-server deployments but does not persist across container rebuilds unless the volume is backed up.
GPU Processing (Optional)
Heavy AI processing (Demucs stem separation, RVC voice cloning) can be offloaded to serverless GPU providers for faster results.
RunPod Serverless
- Sign up at runpod.io
- Create a Serverless Endpoint with a GPU template (A40/A100 recommended)
- Deploy the
runpod_handler.pyfrom the repository as the handler - Set environment variables:
RUNPOD_API_KEY=your_runpod_api_key RUNPOD_ENDPOINT_ID=your_endpoint_id
Modal.com Webhook
- Sign up at modal.com
- Deploy
modal_app.pyas a Modal app - Copy the webhook URL to your environment:
MODAL_WEBHOOK_URL=https://your-org--escenario-audio.modal.run
CPU Fallback
No GPU? No problem. If neither RunPod nor Modal is configured, all processing falls back to CPU on the Celery worker. Stem separation will take 2-5 minutes per track instead of 6-15 seconds, but it works without any external dependencies.
Auto-Updater System
The admin panel includes a one-click deployment system that pulls the latest code from GitHub and rebuilds Docker containers without SSH access.
How It Works
- Admin clicks "Check for Updates" in the admin panel
- Backend executes
git fetchon the host source directory - Compares local HEAD with remote HEAD, reports commits behind
- Admin clicks "Deploy Update"
- Backend executes
git pull+docker compose up -d --buildon host - Containers rebuild with new code, zero-downtime via rolling restart
Required Docker Mounts
These volume mounts in docker-compose.yml are essential for the updater to work:
services:
backend:
volumes:
- /opt/escenario/backend:/opt/escenario/backend # Host source code
- /var/run/docker.sock:/var/run/docker.sock # Docker API access
- /usr/bin/docker:/usr/bin/docker # Docker binary
Security Note: Mounting the Docker socket gives the backend container full Docker control over the host. This is required for the auto-updater but means the container has elevated privileges. Ensure only admin users can trigger the updater endpoint.
API Endpoints
Git Configuration
Ensure the host source directory has a valid git remote configured:
cd /opt/escenario/backend git remote -v # Should show your GitHub repo # If using SSH auth, ensure the host has a valid deploy key # If using HTTPS, configure credential caching: git config credential.helper store
Security Considerations
Authentication & Authorization
| Mechanism | Implementation | Configuration |
|---|---|---|
| Password Hashing | bcrypt via passlib | Cost factor 12 (default) |
| Token Format | JWT (JSON Web Token) | HS256 algorithm |
| Token Expiry | 24 hours | ACCESS_TOKEN_EXPIRE_MINUTES=1440 |
| Admin Guard | is_admin flag on User model | Checked via dependency injection |
| Plan Gating | PlanTier check per endpoint | Enterprise features reject Free/Pro |
Network Security
- PostgreSQL: Only accessible within Docker network (no port mapping to host)
- Redis: Only accessible within Docker network
- Backend API: Binds to
127.0.0.1:8000only (not public) - VST Host: Internal Docker network only (no port mapping)
- Nginx: Only public-facing service (ports 80/443)
CORS Configuration
Only explicitly whitelisted origins are allowed. Configure via ALLOWED_ORIGINS environment variable. Never use wildcard (*) in production.
Firewall (UFW) Recommended Rules
ufw default deny incoming ufw default allow outgoing ufw allow ssh ufw allow 80/tcp ufw allow 443/tcp ufw enable
Recommendations
- Rotate
SECRET_KEYperiodically (invalidates all active sessions) - Use strong, unique database passwords
- Enable Nginx rate limiting for login endpoints
- Set up fail2ban for SSH brute-force protection
- Keep Docker images updated (
docker compose pullweekly) - Monitor
/var/log/nginx/access.logfor anomalies - Back up PostgreSQL daily (see Maintenance section)
Maintenance & Monitoring
Service Logs
# All services docker compose logs -f # Specific service docker compose logs -f backend docker compose logs -f celery-worker docker compose logs -f vst-host # Last 100 lines docker compose logs --tail=100 backend # Nginx logs tail -f /var/log/nginx/access.log tail -f /var/log/nginx/error.log
Database Backups
# Manual backup docker compose exec db pg_dump -U escenario escenario_db > backup_$(date +%Y%m%d).sql # Automated daily backup (add to crontab) 0 3 * * * cd /opt/escenario/backend && docker compose exec -T db pg_dump -U escenario escenario_db | gzip > /opt/escenario/backups/db_$(date +\%Y\%m\%d).sql.gz # Restore from backup docker compose exec -T db psql -U escenario escenario_db < backup_20260522.sql
Health Check Endpoints
| Endpoint | Expected Response | Checks |
|---|---|---|
GET /health | 200 OK | API is responsive |
GET / | 200 OK | Application root |
docker compose ps | All "healthy" | Container status |
Disk Space Management
# Check workspace volume usage docker system df # Prune unused Docker resources docker system prune -f # Check audio workspace size docker compose exec backend du -sh /var/workspace/ # PostgreSQL database size docker compose exec db psql -U escenario -d escenario_db \ -c "SELECT pg_size_pretty(pg_database_size('escenario_db'));"
Restart Services
# Restart a single service docker compose restart backend # Rebuild and restart (after code changes) docker compose up -d --build backend celery-worker # Full stack restart docker compose down && docker compose up -d # Reload Nginx (after config changes) nginx -t && systemctl reload nginx
Licensing & White-Label
EscenarioAI is designed as a self-contained platform that can be white-labeled and deployed under any brand.
Rebranding Checklist
| Item | File/Location | What to Change |
|---|---|---|
| Domain/CORS | .env (ALLOWED_ORIGINS) | Replace all domain references |
| Nginx configs | /etc/nginx/sites-available/ | Update server_name directives |
| SSL certificates | Certbot | Re-run certbot with new domains |
| Landing page | /var/www/escenario/landing/ | Replace branding, logos, copy |
| Admin panel | /var/www/escenario/admin/ | Update title, logos, support URL |
| Frontend | vite.config.js, index.html | Update title, favicon, API URL |
| Email templates | app/services/ | Update sender name/address |
Offline Operation
The platform can run fully offline (no external dependencies) with these trade-offs:
| Feature | Online | Offline Alternative |
|---|---|---|
| File Storage | Cloudflare R2 | Local Docker volume (/var/workspace) |
| GPU Processing | RunPod / Modal | Local CPU (Celery worker) |
| AI Chat | OpenAI API | Disabled (remove chat endpoint) |
| VST AI Mapping | OpenAI API | Manual parameter control only |
| SSL Certificates | Let's Encrypt | Self-signed or internal CA |
To run offline, simply leave R2_*, RUNPOD_*, MODAL_*, and OPENAI_* environment variables empty. The platform gracefully degrades to local alternatives.
Scaling Considerations
- Horizontal scaling: Add more Celery workers by increasing
--concurrencyor deploying additional worker containers - Database scaling: PostgreSQL supports read replicas for high-read workloads
- CDN: Put Cloudflare or similar CDN in front of the landing page and static assets
- Load balancing: Multiple backend instances behind Nginx upstream for high availability
- Storage: R2 provides virtually unlimited storage with no egress fees
Support & Updates
Licensed deployments receive:
- Access to the private GitHub repository with all source code
- One-click updates via the admin panel auto-updater
- Database migrations handled automatically by SQLAlchemy
- Docker images pinned to stable versions for reproducibility
Self-Contained: The entire platform (frontend, backend, database, cache, VST host) runs from a single docker compose up -d command. No external services are required for core functionality.