642 lines
17 KiB
Markdown
642 lines
17 KiB
Markdown
# 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.
|