Turn your Plex library into themed virtual TV channels in Tunarr
Programmarr is a self-hosted web app that exports your Plex library, lets you feed it to an LLM, and deploys the results as themed virtual TV channels in Tunarr — with a web UI that feels like Sonarr or Radarr.
Requires: Tunarr + Plex
docker compose up -dThat's it — the image is pre-built on GHCR and pulls automatically. No local build step needed.
http://<your-server-ip>:7979
First run shows an onboarding wizard — create a login, enter your Tunarr and Plex URLs, done.
Add Watchtower to your compose file and updates happen automatically — no SSH, no manual pulls, no Portainer. Watchtower checks every 5 minutes and restarts the container if a new image is available:
services:
programmarr:
image: ghcr.io/alpinearchitecture/programmarr:latest
container_name: programmarr
restart: unless-stopped
ports:
- "7979:7979"
volumes:
- ./data:/data
watchtower:
image: containrrr/watchtower
container_name: watchtower
environment:
- DOCKER_API_VERSION=1.44
volumes:
- /var/run/docker.sock:/var/run/docker.sock
command: --interval 300 programmarr
restart: unless-stoppedNote: The
DOCKER_API_VERSION=1.44env var is required on newer Docker engines (TrueNAS, Docker Desktop 4.x+). Without it, Watchtower crash-loops with "client version 1.25 is too old".
Or update manually any time:
docker compose pull && docker compose up -dPaste this as a complete compose file in Apps → Custom App:
services:
programmarr:
image: ghcr.io/alpinearchitecture/programmarr:latest
container_name: programmarr
restart: unless-stopped
ports:
- "7979:7979"
volumes:
- /mnt/YourPool/AppData/programmarr/data:/data
watchtower:
image: containrrr/watchtower
container_name: watchtower
environment:
- DOCKER_API_VERSION=1.44
volumes:
- /var/run/docker.sock:/var/run/docker.sock
command: --interval 300 programmarr
restart: unless-stoppedReplace /mnt/YourPool/AppData/programmarr/data with a real path on your pool.
| Path | How it works |
|---|---|
| AI Path | Export your library → copy prompt + CSV into any LLM → paste the result back → deploy |
| No-AI Path | Auto-generates decade, genre, and TV marathon channels from your metadata |
| Collections | Turns each Plex collection (Kometa, Trakt, Letterboxd) into its own channel |
All three paths end with a probe (dry run) → deploy to Tunarr. The app streams live output to the browser so you can watch it work.
- Channel logo fetching — pulls TMDB clearlogos for single-show/movie channels
- Plex DVR sync — maps new channels into the Plex Live TV guide automatically
- Channel editor — edit names, numbers, shuffle mode, and content lists in the browser
- Optional basic auth — set a username/password if you expose the UI outside your LAN
Everything is set through the UI. Config is stored in ./data/config.json (bind-mounted, never baked into the image).
| Field | Required | Notes |
|---|---|---|
| Tunarr URL | Yes | e.g. http://192.168.1.10:8000 |
| Plex URL | Yes | e.g. http://192.168.1.10:32400 |
| Plex Token | Yes | How to find yours |
| TMDB API Key | No | Free at themoviedb.org — only needed for channel logos |
If you prefer the terminal, all the same functionality is available via programmarr.py:
python programmarr.pyThe Python scripts have zero dependencies beyond the standard library and work standalone without Docker.
Built with Claude Code. Made possible by Tunarr, Plex, TMDB, and Kometa.




