# Dispatcharr Portable for macOS (Apple Silicon) --- ## ⚠️ ⚠️ ⚠️ EXPERIMENTAL - NO OFFICIAL SUPPORT ⚠️ ⚠️ ⚠️ ### 🚨 READ THIS BEFORE INSTALLING 🚨 **THIS IS AN UNSUPPORTED, EXPERIMENTAL INSTALLATION METHOD** - ❌ **NO SUPPORT** will be provided in Discord - ❌ **NO SUPPORT** will be provided in GitHub Issues - ❌ **NOT OFFICIALLY MAINTAINED** by the Dispatcharr team - ❌ **USE AT YOUR OWN RISK** **The ONLY officially supported installation method is Docker.** If you use this portable installation: - You are on your own for troubleshooting - Do NOT ask for help in Discord or GitHub - Do NOT open issues related to this installation method - The maintainers reserve the right to close any support requests **If you need support, use the official Docker installation.** --- **A completely self-contained, leave-no-trace installation** This installation method creates a fully portable Dispatcharr instance that works like a Docker container but runs natively on macOS with Apple Silicon hardware acceleration. ## 🎯 What Makes This Special ### Zero System Impact - ✅ **No Homebrew packages** installed globally - ✅ **No system users** created - ✅ **No system files** modified - ✅ **No launchd/systemd** services - ✅ **Everything in one directory** - ✅ **Delete directory = complete removal** ### Complete Portability - Move the installation anywhere - Copy to external drive - Backup by copying directory - Share with others - Multiple installations possible ### Hardware Acceleration - Built-in VideoToolbox support - Native Apple Silicon (ARM64) - FFmpeg with hardware encoding/decoding - PyTorch with MPS (Metal Performance Shaders) ## 📋 Requirements - **macOS 12.0+** (Monterey or later) - **Apple Silicon** (M1/M2/M3/M4) - **Xcode Command Line Tools** - **OpenSSL** (via Homebrew) - **15GB+ free disk space** - **8GB+ RAM** recommended ## 🚀 Installation ### Install Prerequisites ```bash # Install Xcode Command Line Tools xcode-select --install # Install Homebrew (if not already installed) /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" # Install OpenSSL (required for Python SSL support) brew install openssl@3 ``` **Note:** While we try to minimize system dependencies, OpenSSL is required for Python's SSL module. The installer will detect and use Homebrew's OpenSSL automatically. ### Run the Installer ```bash # Download curl -O https://git.seth.services/seth-public/dispatcharr-apple-silicon/raw/branch/main/macos_portable_install.sh # Make executable chmod +x macos_portable_install.sh # Run (no sudo needed - builds from source with optimizations) ./macos_portable_install.sh # OR run with sudo to use prebuilt binaries where possible (faster) sudo ./macos_portable_install.sh ``` **Running with sudo:** - Uses prebuilt Python installer (saves ~3-5 minutes) - Still uses optimized builds for FFmpeg (VideoToolbox) - All files are still owned by your user (chown applied) **Running without sudo (recommended):** - Builds Python from source (~3-5 minutes) - No system modifications - Truly portable installation The installer will: 1. Ask you to confirm understanding of experimental nature 2. **Ask which branch to install** (main/dev/custom) 3. Ask for installation directory (default: `~/Dispatcharr`) 4. **Show live progress bar** throughout the installation 5. Clone the Dispatcharr repository 6. **Auto-detect required versions** from Dockerfile and requirements 7. Download and build all dependencies (~15-20 minutes with fast builds) 8. Configure everything automatically 9. Create launcher scripts 10. **Display completion summary** with all details ### Progress Tracking The installer features a **visual progress bar** that shows: - Current step being executed - Progress percentage - Step number (e.g., "Step 5/15") The display updates in real-time and clears the screen to show only current progress, making it easy to track the installation without scrolling through logs. **Build logs** from compilation steps (Python, PostgreSQL, Redis, FFmpeg) are saved to `deps/*.log` files for troubleshooting if needed. **Example Progress Display:** ``` ╔════════════════════════════════════════════════════════════════════════════╗ ║ DISPATCHARR PORTABLE INSTALLATION ║ ╚════════════════════════════════════════════════════════════════════════════╝ Progress: [##################### ] 45% Step 7/15 ──────────────────────────────────────────────────────────────────────────── Current Step: Building FFmpeg with VideoToolbox (15-20 min)... ──────────────────────────────────────────────────────────────────────────── Compiling (this takes the longest)... ``` ### Branch Selection During installation, you can choose: - **main** - Stable releases (recommended for production) - **dev** - Development branch (latest features, may be unstable) - **custom** - Enter any specific branch name Your chosen branch is saved and used for updates. ### Automatic Version Detection The script automatically detects the correct versions to install by analyzing: - `docker/DispatcharrBase` - Python, PostgreSQL, and Redis versions - `docker/Dockerfile` - Node.js version - `requirements.txt` - Python package dependencies This ensures your portable installation uses the **exact same versions** as the official Docker container, guaranteeing compatibility. ### What Gets Installed Dependencies are downloaded using the fastest method available: - **Python** - Built from source (fast build, ~3-5 min) - **PostgreSQL** - Prebuilt binary if available, otherwise compiled from source (~5-8 min) - **Redis** - Built from source (quick 2-3 minute compile) - **nginx** - Built from source (~2-3 minutes) - **Node.js** - Official prebuilt binary (instant) - **FFmpeg** - Built from source with VideoToolbox hardware acceleration (~10-15 min) - **PyTorch** - Official Apple Silicon build with Metal Performance Shaders (MPS) support **Why build some from source?** - **Python**: Required for SSL support with portable OpenSSL - **FFmpeg**: VideoToolbox support requires custom build flags - **nginx**: Built with HTTP/2 and SSL support for optimal performance - **PostgreSQL/Redis**: Prebuilt used when available to save time **Build Speed:** - Uses all CPU cores for parallel compilation - Python builds in ~3-5 minutes (skips PGO optimizations) - Total installation: ~20-25 minutes on modern Apple Silicon **Architecture:** The portable installation uses the **exact same architecture as Docker**: - nginx as reverse proxy (routes traffic to uWSGI and Daphne) - uWSGI for WSGI/HTTP requests (streaming optimized) - Daphne for WebSocket connections - This ensures identical behavior and compatibility **Hardware Acceleration:** - FFmpeg uses VideoToolbox for video encoding/decoding - PyTorch uses Metal Performance Shaders (MPS) for AI/ML tasks - Both leverage Apple Silicon's specialized hardware ## 📁 Directory Structure ``` ~/Dispatcharr/ # Installation root ├── dispatcharr.sh # Main launcher script ├── UNINSTALL.sh # Complete removal script ├── README.txt # Quick reference ├── VERSIONS.txt # Installed versions info ├── .env # Configuration & credentials │ ├── app/ # Dispatcharr application (git repo) │ ├── manage.py │ ├── env/ # Python virtual environment │ └── frontend/dist/ # Built assets │ ├── data/ # YOUR DATA (recordings, configs, etc.) │ ├── db/ # PostgreSQL data directory │ ├── recordings/ │ ├── logos/ │ ├── uploads/ │ ├── m3us/ │ ├── epgs/ │ ├── plugins/ │ ├── media/ │ └── logo_cache/ │ ├── deps/ # All dependencies (self-contained) │ ├── python/ │ ├── postgresql/ │ ├── redis/ │ ├── nginx/ │ ├── ffmpeg/ │ └── node/ │ ├── runtime/ # Runtime files (PIDs, sockets) │ ├── pids/ │ └── sockets/ │ └── logs/ # All log files ├── postgresql.log ├── redis.log ├── nginx-access.log ├── nginx-error.log ├── uwsgi.log ├── daphne.log ├── celery.log └── celerybeat.log ``` ## 🎮 Usage All management is done through the `dispatcharr.sh` script: ```bash cd ~/Dispatcharr # Start all services ./dispatcharr.sh start # Stop all services ./dispatcharr.sh stop # Restart everything ./dispatcharr.sh restart # Check service status ./dispatcharr.sh status # View live logs ./dispatcharr.sh logs # Update to latest on current branch ./dispatcharr.sh update # Switch to a different branch ./dispatcharr.sh switch-branch dev ./dispatcharr.sh switch-branch main # Show version and branch info ./dispatcharr.sh version ``` ### Accessing the Web Interface After starting, open: **http://localhost:9191** The architecture mirrors Docker exactly: - **nginx** (port 9191) - Reverse proxy for all traffic - **uWSGI** (Unix socket + HTTP 5656) - Django WSGI app for HTTP/streaming - **Daphne** (port 8001) - Django ASGI app for WebSockets (nginx proxies `/ws/` requests) All traffic goes through nginx on port 9191, which routes to the appropriate backend. ## 🎬 VideoToolbox Hardware Acceleration FFmpeg is built with full VideoToolbox support for Apple Silicon. ### Verify Support ```bash cd ~/Dispatcharr ./deps/ffmpeg/bin/ffmpeg -hwaccels # Should show: videotoolbox ``` ### FFmpeg Parameters for Dispatcharr Use these parameters in Dispatcharr's FFmpeg settings for hardware-accelerated encoding: **H.264 Hardware Encoding (Recommended):** ``` -user_agent {userAgent} -i {streamUrl} -c:v h264_videotoolbox -b:v 5M -maxrate 5M -bufsize 10M -c:a copy -f mpegts pipe:1 ``` **HEVC/H.265 Hardware Encoding:** ``` -user_agent {userAgent} -i {streamUrl} -c:v hevc_videotoolbox -b:v 5M -maxrate 5M -bufsize 10M -c:a copy -f mpegts pipe:1 ``` **With Hardware Decoding + Encoding:** ``` -hwaccel videotoolbox -user_agent {userAgent} -i {streamUrl} -c:v h264_videotoolbox -b:v 5M -maxrate 5M -bufsize 10M -c:a copy -f mpegts pipe:1 ``` **Variable Quality (instead of constant bitrate):** ``` -user_agent {userAgent} -i {streamUrl} -c:v h264_videotoolbox -q:v 65 -c:a copy -f mpegts pipe:1 ``` **With Specific Profile:** ``` -user_agent {userAgent} -i {streamUrl} -c:v h264_videotoolbox -profile:v high -b:v 5M -maxrate 5M -bufsize 10M -c:a copy -f mpegts pipe:1 ``` **Realtime Mode (for live streams):** ``` -user_agent {userAgent} -i {streamUrl} -c:v h264_videotoolbox -realtime 1 -b:v 5M -maxrate 5M -bufsize 10M -c:a copy -f mpegts pipe:1 ``` ### Parameter Notes - `-b:v 5M -maxrate 5M -bufsize 10M` are **required** for stable encoding - `-c:a copy` copies audio without re-encoding (saves CPU) - `-f mpegts pipe:1` outputs MPEG-TS format to stdout - `-q:v 65` uses variable quality (1-100, lower = better quality) - `-profile:v high` sets H.264 profile (baseline, main, or high) - `-realtime 1` optimizes for live streaming with lower latency ## 🔧 Configuration ### Check Installed Versions ```bash # View installed versions cat ~/Dispatcharr/VERSIONS.txt # Or verify directly ~/Dispatcharr/deps/python/bin/python3 --version ~/Dispatcharr/deps/postgresql/bin/postgres --version ~/Dispatcharr/deps/redis/bin/redis-server --version ~/Dispatcharr/deps/node/bin/node --version ~/Dispatcharr/deps/ffmpeg/bin/ffmpeg -version ``` ### Database Credentials Stored in `.env` file (automatically generated): ```bash cat ~/Dispatcharr/.env ``` ### Modify Ports Edit `.env` and restart: ```bash nano ~/Dispatcharr/.env # Change HTTP_PORT or WEBSOCKET_PORT ./dispatcharr.sh restart ``` ### Django Settings For advanced configuration: ```bash nano ~/Dispatcharr/app/dispatcharr/settings.py ``` ## 📊 Monitoring ### View Logs ```bash # All logs (live) ./dispatcharr.sh logs # Specific service tail -f ~/Dispatcharr/logs/nginx-access.log tail -f ~/Dispatcharr/logs/uwsgi.log tail -f ~/Dispatcharr/logs/celery.log tail -f ~/Dispatcharr/logs/postgresql.log # Errors only grep ERROR ~/Dispatcharr/logs/*.log ``` ### Check Status ```bash ./dispatcharr.sh status ``` Output shows running/stopped state of each service: - PostgreSQL - Redis - nginx (reverse proxy) - uWSGI (Django/WSGI) - Daphne (WebSockets/ASGI) - Celery worker (background tasks) - Celery beat (scheduler) ### Resource Usage ```bash # Find processes ps aux | grep dispatcharr # Memory usage cd ~/Dispatcharr du -sh data/db # Database size du -sh data/ # Your data size ``` ## 🔄 Updates ### Update on Current Branch ```bash cd ~/Dispatcharr ./dispatcharr.sh update ``` This will: 1. Stop all services 2. Pull latest code from your current branch 3. Update Python dependencies 4. Rebuild frontend 5. Run database migrations 6. Restart services ### Switch Branches You can switch between branches (e.g., stable ↔ development): ```bash # Switch to development branch ./dispatcharr.sh switch-branch dev # Switch back to stable ./dispatcharr.sh switch-branch main # Switch to any custom branch ./dispatcharr.sh switch-branch feature/new-feature ``` Branch switching will: 1. Stop services 2. Checkout the new branch 3. Update all dependencies 4. Rebuild frontend 5. Run migrations 6. Update `.env` with new branch 7. Restart services ### Check Current Version ```bash # Show detailed version info ./dispatcharr.sh version # Output shows: # - Installed dependency versions # - Current branch # - Current commit # - Last update date ``` ### Update Dependency Versions If Dispatcharr updates its Python/Node/PostgreSQL requirements: **Option 1: Update in place (if minor version changes)** ```bash ./dispatcharr.sh update ``` **Option 2: Reinstall (if major version changes)** ```bash # Backup your data cp -r ~/Dispatcharr/data ~/Dispatcharr-data-backup # Stop and remove old installation cd ~/Dispatcharr ./dispatcharr.sh stop cd ~ rm -rf ~/Dispatcharr # Reinstall with new versions ./macos_portable_install.sh # Choose same branch # Restore data cp -r ~/Dispatcharr-data-backup/* ~/Dispatcharr/data/ # Start services cd ~/Dispatcharr ./dispatcharr.sh start ``` Your PostgreSQL database is preserved in the data directory! The entire installation is portable: ```bash # 1. Stop services cd ~/Dispatcharr ./dispatcharr.sh stop # 2. Move the directory mv ~/Dispatcharr /Volumes/External/Dispatcharr # 3. Start from new location cd /Volumes/External/Dispatcharr ./dispatcharr.sh start ``` Works across: - Different folders - External drives - Network shares - Different Macs (same architecture) ## 💾 Backup & Restore ### Full Backup ```bash # Stop services cd ~/Dispatcharr ./dispatcharr.sh stop # Backup everything tar -czf dispatcharr-backup-$(date +%Y%m%d).tar.gz ~/Dispatcharr # Or just copy the directory cp -r ~/Dispatcharr ~/Dispatcharr-backup ``` ### Data-Only Backup ```bash # Just your recordings and configs tar -czf dispatcharr-data-$(date +%Y%m%d).tar.gz ~/Dispatcharr/data ``` ### Restore ```bash # Extract backup tar -xzf dispatcharr-backup-20250103.tar.gz -C ~ # Start services cd ~/Dispatcharr ./dispatcharr.sh start ``` ## 🔄 Updates ### Automatic Update ```bash cd ~/Dispatcharr ./dispatcharr.sh update ``` This will: 1. Stop services 2. Pull latest code 3. Update Python dependencies 4. Rebuild frontend 5. Run migrations 6. Restart services ### Manual Update ```bash ./dispatcharr.sh stop cd ~/Dispatcharr/app git pull origin main source env/bin/activate pip install -r requirements.txt cd frontend npm install --legacy-peer-deps npm run build cd ~/Dispatcharr/app python manage.py migrate python manage.py collectstatic --noinput cd ~/Dispatcharr ./dispatcharr.sh start ``` ## 🗑️ Complete Removal ### Using the Uninstaller ```bash cd ~/Dispatcharr ./UNINSTALL.sh # Type: DELETE EVERYTHING ``` This will: 1. Stop all services 2. Delete the entire directory 3. Leave no traces ### Manual Removal ```bash cd ~/Dispatcharr ./dispatcharr.sh stop cd ~ rm -rf ~/Dispatcharr ``` That's it! No system cleanup needed.