17 KiB
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
# 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
# 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:
- Ask you to confirm understanding of experimental nature
- Ask which branch to install (main/dev/custom)
- Ask for installation directory (default:
~/Dispatcharr) - Show live progress bar throughout the installation
- Clone the Dispatcharr repository
- Auto-detect required versions from Dockerfile and requirements
- Download and build all dependencies (~15-20 minutes with fast builds)
- Configure everything automatically
- Create launcher scripts
- 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 versionsdocker/Dockerfile- Node.js versionrequirements.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:
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
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 10Mare required for stable encoding-c:a copycopies audio without re-encoding (saves CPU)-f mpegts pipe:1outputs MPEG-TS format to stdout-q:v 65uses variable quality (1-100, lower = better quality)-profile:v highsets H.264 profile (baseline, main, or high)-realtime 1optimizes for live streaming with lower latency
🔧 Configuration
Check Installed Versions
# 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):
cat ~/Dispatcharr/.env
Modify Ports
Edit .env and restart:
nano ~/Dispatcharr/.env
# Change HTTP_PORT or WEBSOCKET_PORT
./dispatcharr.sh restart
Django Settings
For advanced configuration:
nano ~/Dispatcharr/app/dispatcharr/settings.py
📊 Monitoring
View Logs
# 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
./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
# 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
cd ~/Dispatcharr
./dispatcharr.sh update
This will:
- Stop all services
- Pull latest code from your current branch
- Update Python dependencies
- Rebuild frontend
- Run database migrations
- Restart services
Switch Branches
You can switch between branches (e.g., stable ↔ development):
# 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:
- Stop services
- Checkout the new branch
- Update all dependencies
- Rebuild frontend
- Run migrations
- Update
.envwith new branch - Restart services
Check Current Version
# 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)
./dispatcharr.sh update
Option 2: Reinstall (if major version changes)
# 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:
# 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
# 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
# Just your recordings and configs
tar -czf dispatcharr-data-$(date +%Y%m%d).tar.gz ~/Dispatcharr/data
Restore
# Extract backup
tar -xzf dispatcharr-backup-20250103.tar.gz -C ~
# Start services
cd ~/Dispatcharr
./dispatcharr.sh start
🔄 Updates
Automatic Update
cd ~/Dispatcharr
./dispatcharr.sh update
This will:
- Stop services
- Pull latest code
- Update Python dependencies
- Rebuild frontend
- Run migrations
- Restart services
Manual Update
./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
cd ~/Dispatcharr
./UNINSTALL.sh
# Type: DELETE EVERYTHING
This will:
- Stop all services
- Delete the entire directory
- Leave no traces
Manual Removal
cd ~/Dispatcharr
./dispatcharr.sh stop
cd ~
rm -rf ~/Dispatcharr
That's it! No system cleanup needed.