A self-hosted alternative to Overseerr that keeps things simple. Search TMDB for movies and TV shows, add them to request lists, and let Sonarr/Radarr pull them in via native import list endpoints. Runs fully serverless on AWS for under a dollar a month β no servers to maintain, no ports to open. A Docker Compose option is also available for local or self-hosted setups.
- No open ports β Caddy auto-HTTPS or CloudFront handles TLS, nothing exposed
- Native import lists β Sonarr and Radarr pull directly, no webhooks or middleware
- Plex integration β auto-marks requests as added, syncs "In Library" badges
- Push notifications β web push alerts when requested media lands in your library
- PWA support β installable on iOS and Android with proper icons
- Localized β English, Spanish, French, German (auto-detects browser language)
- Two deployment paths β Docker Compose or AWS serverless (Lambda + DynamoDB + CloudFront)
Architecture: Docker
βββββββββββββββ βββββββββββββββ βββββββββββββββ
β Browser ββββββΆβ Caddy ββββββΆβ Frontend β
β β β (Reverse β β (Svelte) β
βββββββββββββββ β Proxy + β βββββββββββββββ
β HTTPS) β βββββββββββββββ
β ββββββΆβ Backend β
βββββββββββββββ β (FastAPI) β
ββββββββ¬βββββββ
ββββββββΌβββββββ
β SQLite β
βββββββββββββββ
Architecture: AWS Serverless (Low Cost)
βββββββββββββββ βββββββββββββββ βββββββββββββββ
β Browser ββββββΆβ CloudFront ββββββΆβ S3 Bucket β
β β β (CDN) β β (Frontend) β
βββββββββββββββ β β βββββββββββββββ
β β βββββββββββββββ
β ββββββΆβ Lambda ββββββΆ TMDB API
βββββββββββββββ β (FastAPI) β
ββββββββ¬βββββββ
ββββββββΌβββββββ
β DynamoDB β
β (on-demand) β
βββββββββββββββ
- AWS CLI configured
- Terraform >= 1.0
- Route53 hosted zone for your domain
- TMDB API key
-
Configure Terraform variables:
cd terraform cp terraform.tfvars.example terraform.tfvars # Edit terraform.tfvars with your settings
-
Deploy infrastructure:
terraform init terraform plan terraform apply
-
Deploy application:
cd .. ./deploy.sh # Deploy everything (terraform, backend, frontend) ./deploy.sh --skip-tf # Skip terraform, deploy backend + frontend only ./deploy.sh --backend # Backend Lambda only ./deploy.sh --frontend # Frontend + CloudFront invalidation only
| Service | Monthly Cost |
|---|---|
| DynamoDB | $0 (free tier: 25GB + 25 WCU/RCU) |
| Lambda | $0 (free tier: 1M requests) |
| CloudFront | $0 (free tier: 1TB transfer) |
| S3 | $0 (free tier: 5GB) |
| Secrets Manager | ~$0.40 |
| Route53 | ~$0.50 (hosted zone) |
| Total | ~$0.50-1/month |
- Docker and Docker Compose
- TMDB API Key (free at https://www.themoviedb.org/settings/api)
-
Clone and configure:
git clone <repo-url> cd stellarr cp .env.example .env # Edit .env with your settings
-
Start the application:
# Development (HTTP only) docker compose up -d # Production (automatic HTTPS via Caddy) docker compose -f docker-compose.prod.yml up -d
-
Access at
http://localhostorhttps://your-domain.com
| Endpoint | Format | Description |
|---|---|---|
/list/radarr |
JSON | Recommended - StevenLu Custom format with IMDB IDs |
/rss/movies |
RSS | Alternative RSS format |
Setup: Settings β Import Lists β Custom Lists β StevenLu Custom
| Endpoint | Format | Description |
|---|---|---|
/list/sonarr |
JSON | Recommended - Custom List format with TVDB IDs |
/rss/tv |
RSS | Alternative RSS format |
Setup: Settings β Import Lists β Custom Lists
If FEED_TOKEN is set, append ?token=YOUR_TOKEN to feed URLs.
The application fetches external IDs from TMDB when items are requested:
- Movies: IMDB ID (for Radarr)
- TV Shows: TVDB ID (for Sonarr)
Items missing these IDs will show a warning indicator and won't appear in the respective feeds.
Configure Plex to send webhooks when new media is added:
- In Plex: Settings β Webhooks β Add Webhook
- URL:
https://your-domain.com/webhook/plex?token=YOUR_PLEX_WEBHOOK_TOKEN - Stellarr will auto-mark matching requests as "Added"
The webhook also adds items to the library table, enabling "In Library" badges on search results.
For initial library population, use the sync script on your Plex server:
cd scripts
pip install -r requirements.txt
python plex-sync.py \
--plex-url http://localhost:32400 \
--plex-token YOUR_PLEX_TOKEN \
--stellarr-url https://your-domain.com \
--sync-token YOUR_PLEX_WEBHOOK_TOKENThis syncs all movies and TV shows from Plex, enabling "In Library" badges even for items added before the webhook was configured.
- HTTPS everywhere β TLS 1.2+ enforced via CloudFront
- Signed session tokens β HMAC-SHA256 with 30-day expiry
- Secrets Manager β API keys stored securely
- Private S3 β Frontend only accessible via CloudFront
- WAF (optional) β Rate limiting and threat protection (~$8/month extra)
API Reference
| Endpoint | Method | Description |
|---|---|---|
/api/auth/params |
GET | Get PBKDF2 iterations for login |
/api/auth/verify |
POST | Verify password, returns session token |
/api/search |
POST | Search TMDB |
/api/library-status |
GET | Get library IDs and pending requests |
/api/request |
POST | Add a request |
/api/request/{type}/{id} |
DELETE | Remove a request |
/api/requests |
GET | List all requests |
/api/feeds |
GET | Get feed URLs and setup info |
/api/health |
GET | Health check |
/trending-{type}-{locale}.json |
GET | Trending media (static S3, 1hr cache) |
| Endpoint | Format | For |
|---|---|---|
/list/radarr |
JSON | Radarr StevenLu Custom |
/list/sonarr |
JSON | Sonarr Custom Lists |
/rss/movies |
RSS | Radarr RSS List |
/rss/tv |
RSS | Generic TV RSS |
/rss/all |
RSS | Combined RSS |
| Endpoint | Method | Description |
|---|---|---|
/webhook/plex?token=XXX |
POST | Plex webhook - marks requests as added |
/sync/library?media_type=movie&token=XXX |
POST | Bulk sync library items |
Environment Variables
| Variable | Description | Required |
|---|---|---|
APP_SECRET_KEY |
Application secret key | Yes |
PRESHARED_PASSWORD |
User access password | Yes |
TMDB_API_KEY |
TMDB API key | Yes |
FEED_TOKEN |
Token for feed endpoint auth | No |
PLEX_WEBHOOK_TOKEN |
Token for Plex webhook/sync endpoints | No |
PLEX_SERVER_NAME |
Filter webhooks to specific Plex server | No |
TVDB_API_KEY |
TVDB API key (resolves episode webhooks to parent show) | No |
DOMAIN |
Your domain (for HTTPS) | Production |
Project Structure
stellarr/
βββ backend/ # Docker backend (SQLite)
βββ backend-lambda/ # AWS Lambda backend (DynamoDB)
βββ frontend/ # Svelte SPA
βββ caddy/ # Caddy configs
βββ terraform/ # AWS infrastructure
β βββ main.tf
β βββ dynamodb.tf # DynamoDB table
β βββ lambda.tf # Lambda function
β βββ frontend.tf # S3 + CloudFront
β βββ secrets.tf # Secrets Manager
β βββ waf.tf # AWS WAF (optional)
β βββ outputs.tf
βββ docker-compose.yml
βββ docker-compose.prod.yml
Feed Format Details
[
{"title": "Movie Name (2023)", "imdb_id": "tt1234567"},
{"title": "Another Movie (2024)", "imdb_id": "tt7654321"}
][
{"tvdbId": "75837"},
{"tvdbId": "77847"}
]MIT