Skip to content

ryantenney/stellarr

Repository files navigation

Stellarr

A lightweight media request system for Sonarr & Radarr β€” no open ports required.

License: MIT Docker AWS Lambda Plex


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.

Highlights

  • 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)

Deployment Options

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) β”‚
                                        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Quick Start: AWS Serverless

Prerequisites

  • AWS CLI configured
  • Terraform >= 1.0
  • Route53 hosted zone for your domain
  • TMDB API key

Setup

  1. Configure Terraform variables:

    cd terraform
    cp terraform.tfvars.example terraform.tfvars
    # Edit terraform.tfvars with your settings
  2. Deploy infrastructure:

    terraform init
    terraform plan
    terraform apply
  3. 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

AWS Cost Estimate

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

Quick Start: Docker

Prerequisites

Setup

  1. Clone and configure:

    git clone <repo-url>
    cd stellarr
    cp .env.example .env
    # Edit .env with your settings
  2. Start the application:

    # Development (HTTP only)
    docker compose up -d
    
    # Production (automatic HTTPS via Caddy)
    docker compose -f docker-compose.prod.yml up -d
  3. Access at http://localhost or https://your-domain.com


Import Lists for Sonarr/Radarr

Radarr (Movies)

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

Sonarr (TV Shows)

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

Feed Token Protection

If FEED_TOKEN is set, append ?token=YOUR_TOKEN to feed URLs.

External ID Handling

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.


Plex Integration

Webhook Setup

Configure Plex to send webhooks when new media is added:

  1. In Plex: Settings β†’ Webhooks β†’ Add Webhook
  2. URL: https://your-domain.com/webhook/plex?token=YOUR_PLEX_WEBHOOK_TOKEN
  3. Stellarr will auto-mark matching requests as "Added"

The webhook also adds items to the library table, enabling "In Library" badges on search results.

Library Sync Script

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_TOKEN

This syncs all movies and TV shows from Plex, enabling "In Library" badges even for items added before the webhook was configured.


Security

  • 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

Core Endpoints

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)

Feed Endpoints

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

Webhook & Sync Endpoints

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

Radarr JSON (StevenLu Custom)

[
  {"title": "Movie Name (2023)", "imdb_id": "tt1234567"},
  {"title": "Another Movie (2024)", "imdb_id": "tt7654321"}
]

Sonarr JSON (Custom Lists)

[
  {"tvdbId": "75837"},
  {"tvdbId": "77847"}
]

Sources

License

MIT

About

Lightweight Alternative to Overseerr

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •