# StreamHoard — Deployment on a Proxmox LAMP host StreamHoard is FastAPI + MongoDB + React. It runs happily alongside your existing LAMP stack (Apache/MySQL/PHP) because we run everything in Docker containers on their own network. Apache keeps port 80/443, MySQL is untouched, StreamHoard uses whatever port you pick. --- ## Prerequisites on the Proxmox host (or LXC / VM) ```bash # Ubuntu/Debian sudo apt update sudo apt install -y docker.io docker-compose-plugin git sudo systemctl enable --now docker # Verify docker compose version ``` If you already have Docker and Compose v2, skip this step. --- ## Deploy ```bash # 1. Clone the repo git clone https://github.com/YOU/kino-media-server.git /opt/kino cd /opt/kino # 2. Configure cp .env.compose.example .env nano .env # - Set KINO_HTTP_PORT (default 8080; anything not used by Apache) # - Set MEDIA_ROOT_HOST to your bulk storage path (e.g. /mnt/nas/movies) # - Set a strong JWT_SECRET: openssl rand -hex 32 # - Set a strong ADMIN_PASSWORD # - Optional: change ADMIN_EMAIL # 3. Start docker compose up -d # 4. Check docker compose ps docker compose logs -f backend # confirm "Transcode worker started" ``` Visit `http://:8080` (or whatever `KINO_HTTP_PORT` you set). Log in with the admin credentials from `.env`. --- ## Running behind your existing Apache (optional, recommended) If you already have Apache on port 80/443 with virtual hosts, add a StreamHoard vhost that reverse-proxies to the container. This gives you `https://kino.example.com` instead of `http://ip:8080`. **`/etc/apache2/sites-available/kino.conf`** ```apache ServerName kino.local # or kino.yourdomain.tld ProxyPreserveHost On ProxyRequests Off # SPA + API ProxyPass / http://127.0.0.1:8080/ ProxyPassReverse / http://127.0.0.1:8080/ # Streaming needs disabled buffering SetEnv proxy-sendchunked 1 # Multi-GB uploads LimitRequestBody 21474836480 ``` ```bash sudo a2enmod proxy proxy_http headers sudo a2ensite kino sudo systemctl reload apache2 ``` For HTTPS, either terminate TLS at Apache (add certbot/`SSLEngine on`) or put Caddy in front of it. --- ## Common ops ```bash # Update to latest code cd /opt/kino git pull docker compose build docker compose up -d # Stop docker compose down # Logs docker compose logs -f backend # FastAPI + transcode worker docker compose logs -f frontend # nginx access docker compose logs -f mongo # Shell into backend docker compose exec backend bash # Backup MongoDB docker compose exec mongo mongodump --out /data/db/backup-$(date +%F) ``` --- ## Where does data live? | What | Where | | -------------------------- | ---------------------------------------------------- | | Movie files, HLS, subs | `$MEDIA_ROOT_HOST` on host (bind-mounted) | | MongoDB data | Docker volume `mongo-data` (managed by Docker) | | TMDB / Radarr keys | In MongoDB (`db.settings` collection) | | Uploads via web UI | `$MEDIA_ROOT_HOST/videos/` | To reset everything: `docker compose down -v` (deletes the mongo-data volume). --- ## Coexistence with your LAMP stack | StreamHoard uses | LAMP uses | Conflict? | | ------------------------ | ----------------------- | --------- | | Port `KINO_HTTP_PORT` | Apache 80/443 | No — different ports | | MongoDB (internal only) | MySQL | No — different DBs, Mongo not exposed to host | | ffmpeg (in container) | anything | No | | Docker networks | native host services | No — bridged network | You can happily keep running Wordpress, phpMyAdmin, Nextcloud, whatever on the same box. --- ## Radarr integration If Radarr is running on the same Proxmox host (native or container), point StreamHoard at it via **Admin → Settings → Radarr**: - **URL**: `http://:7878` (use the host IP, not `localhost` — containers can't reach the host's `localhost` unless you add `host.docker.internal`) - **API key**: from Radarr → Settings → General → Security **Important**: For StreamHoard to actually play the imported movies, the path Radarr reports (e.g. `/movies/Inception (2010)/Inception.mkv`) must be **readable from inside the StreamHoard backend container**. Mount Radarr's media path into StreamHoard: ```yaml # docker-compose.yml — extend the backend volumes backend: volumes: - ${MEDIA_ROOT_HOST:-./media}:/media - /mnt/radarr-movies:/mnt/radarr-movies:ro # <— add this ``` Radarr's file paths must be identical inside both Radarr and StreamHoard containers (easiest: match the paths exactly). --- ## Health check ```bash curl -s http://localhost:${KINO_HTTP_PORT:-8080}/api/ | jq # {"app":"StreamHoard","status":"ok"} ``` --- ## Firewalling StreamHoard has no built-in rate limiting or IP allowlist. Since you confirmed **internal network only**, keep it that way: ```bash # ufw example — allow only your LAN sudo ufw allow from 192.168.0.0/16 to any port ${KINO_HTTP_PORT:-8080} sudo ufw deny ${KINO_HTTP_PORT:-8080} ```