Helprr is the dashboard I wanted for my own media server: one place to see what is downloading, what is available, what needs attention, and what I might want to watch next. It is a self-hosted, mobile-first Progressive Web App (PWA) that sits on top of the *arr stack, qBittorrent, Jellyfin, Prowlarr, and a few discovery/request services.
I built it because I wanted an iPhone-friendly way to manage my setup and receive proper push notifications, without paying for another subscription. I have used the iPhone PWA from the first day I created this repository, and I test every feature in the real setup before I call it done. Desktop is not an afterthought either—the larger layout is where the configurable dashboard, analytics, and admin tools are most useful.
[!WARNING] This entire project was built with AI-assisted development—mainly Codex, Claude/Opus, and Gemini. I have tested the features I use and keep using the app every day, but this is still a personal self-hosted project. It is not affiliated with, endorsed by, or a replacement for any service it connects to.
Helprr is not trying to clone every setting from Sonarr, Radarr, Lidarr, qBittorrent, or Jellyfin. I have added the parts I actually need for day-to-day use and kept the rest in the original services. What you see in the app depends on which services you connect and what permissions the signed-in user has.
- Separate mobile and desktop layouts, draggable widgets, and saved dashboard layouts.
- Widgets for the things I want at a glance: library counts, activity, calendar, active downloads, storage, service health, Prowlarr, Jellyfin, Seerr, cleanup, recommendations, insights, watchlists, library gaps, and shortcuts.
- Per-user layout customization, plus shared layouts for administrators.
- Theme, navigation order/visibility, carousel, refresh, timezone, and discovery-layout preferences.
- Global command palette/search (
⌘K/Ctrl+K) when clicking through the sidebar is slower than just searching.
- Browse, search, filter, sort, add, monitor, tag, edit, and manage movies, TV series, music artists/albums, and files.
- TMDb discovery with the rails I use most, plus collections, people, credits, region/language controls, and filters.
- AniList anime and manga discovery, schedules, people/studio pages, library tracking, and Sonarr/Radarr mappings (including auto-mapping).
- Watchlists, scheduled reminders, calendar views, a random-watch picker, and library-gap views for when I do not know what to watch.
- Seerr request visibility and workflow when Seerr is part of the setup.
- Activity queue/history, wanted/missing/cutoff views, manual import, and queue actions.
- qBittorrent details/files, add/start/stop/delete actions, speed limits, alternative limits, and time-windowed bandwidth schedules.
- Rule-based queue, download, and seeding cleanup with dry runs, automation, strikes, and history.
- Prowlarr indexer status, testing, syncing, statistics, and history.
- Jellyfin library and playback views, active sessions/devices, watch-state actions, server tasks/control, and playback analytics.
- Insights pages for checking library growth, downloads, storage, media analysis, and viewing habits without digging through several separate apps.
- Installable PWA with Web Push, device preferences, inbox/history, test notifications, digest events, and per-event controls.
- Per-user accounts, admin/member roles, granular capability overrides, and active-session revocation.
- Multiple Sonarr, Radarr, and Lidarr instances; service health checks; custom HTTP headers for supported integrations behind an authenticating proxy.
- Backup/restore, operation-audit records, log retention, and server-log inspection for the moments when something needs fixing.
All integrations are optional and configured in Settings → Instances. Features that depend on an integration stay unavailable until it is connected.
| Integration | What Helprr uses it for |
|---|---|
| Sonarr | TV library, monitoring, queue/activity, discovery additions, file and episode actions |
| Radarr | Movie library, monitoring, queue/activity, discovery additions, file actions |
| Lidarr | Music library, artist/album actions, monitoring, files |
| qBittorrent | Torrents, transfer state, file priorities, limits, cleanup, bandwidth schedules |
| Prowlarr | Indexers, history, tests, sync, and reliability stats |
| Jellyfin | Library/watch status, sessions/devices, playback analytics, server control |
| TMDb | Movie/TV discovery, metadata, collections, people, and artwork |
| AniList | Anime/manga discovery, schedules, library tracking, and mappings |
| Seerr | Requests and request workflow |
See the upstream compatibility matrix for the exact versions and API contracts verified in the isolated development stack. The matrix is a point-in-time test record, not an unsupported promise covering older or newer releases.
These are the hand-picked captures from my current setup. They are not mockups—the gallery shows the actual desktop and iPhone PWA experience I use for monitoring, discovery, planning, administration, and cleanup.
I recorded two short walkthroughs from the real app so you can get a better feel for it before setting anything up.
This covers the dashboard, Calendar, Discover, notifications, and the settings/admin side of the app.
new-pc-demo-github.mp4
This shows the installable mobile experience, day-to-day browsing, and the push-notification flow.
new-mobile-demo-github.mp4
Docker Compose starts Helprr, PostgreSQL 16, and password-protected Redis 7. It creates named volumes for database, Redis, and log data; waits for database/Redis health; runs pending Prisma migrations before Helprr starts; and exposes Helprr on port 3050.
No clone, no build — Helprr ships as a prebuilt multi-arch image
(amd64/arm64) on ghcr.io/saibarathr/helprr. Each tagged release also carries
the four files needed to install, configure, update, and back up Helprr. Download
the assets from the latest qualified release into this standalone layout:
mkdir -p helprr/scripts && cd helprr
HELPRR_ASSET_BASE=https://github.com/SaiBarathR/helprr/releases/latest/download
curl -fsSL -o docker-compose.yml "$HELPRR_ASSET_BASE/docker-compose.yml"
curl -fsSL -o .env.example "$HELPRR_ASSET_BASE/env.example"
curl -fsSL -o scripts/setup-env.sh "$HELPRR_ASSET_BASE/setup-env.sh"
curl -fsSL -o scripts/backup.sh "$HELPRR_ASSET_BASE/backup.sh"
chmod 700 scripts/setup-env.sh scripts/backup.shFor an exact release, use
HELPRR_ASSET_BASE=https://github.com/SaiBarathR/helprr/releases/download/vX.Y.Z
instead, then set HELPRR_VERSION=X.Y.Z in .env after generating it. Keep the
Compose file and both helpers from the same release.
Generate all required secrets and create .env:
./scripts/setup-env.shThe helper uses independent URL-safe secrets, writes the completed file with mode
0600, never prints secret values, and refuses to overwrite an existing .env.
Open .env to retrieve the generated bootstrap APP_PASSWORD, then review the
timezone and optional settings before the first start. You may replace the generated
bootstrap password with your own strong password before first boot.
The helper fills these required variables:
POSTGRES_PASSWORD
REDIS_PASSWORD
APP_PASSWORD
JWT_SECRET
TZ=Etc/UTC
APP_PASSWORD creates the bootstrap administrator on first boot. Its username is admin by default, or the value of HELPRR_ADMIN_USERNAME. Changing APP_PASSWORD later does not change an existing user's password.
New local Helprr passwords must contain at least 15 characters; existing shorter
passwords remain valid until they are reset. Jellyfin sign-in continues to use the
password policy configured by Jellyfin.
For push notifications, also set the Web Push keys — they are runtime
configuration, no rebuild needed (generate a pair with
npx web-push generate-vapid-keys):
VAPID_SUBJECT=mailto:you@example.com
VAPID_PUBLIC_KEY=generated-public-key
VAPID_PRIVATE_KEY=generated-private-keyThe normal Compose file uses the qualified stable channel. Pin a specific
version with HELPRR_VERSION in .env. Use the isolated development stack
below for edge or source builds; never run them against production data.
docker compose pull
docker compose up -d
docker compose psOpen http://YOUR_SERVER:3050, sign in with the bootstrap account, then connect services in Settings → Instances.
Use docker compose logs -f helprr to follow startup. GET /api/health is an
unauthenticated liveness probe that checks only whether the Node process responds.
GET /api/ready is a separate unauthenticated readiness probe; it returns HTTP 200
only when PostgreSQL, Redis, and the shipped Prisma migration history are ready, or
HTTP 503 with redacted component status otherwise.
Maintainers and contributors can run development beside stable on the same Docker host. The standalone development Compose file uses its own containers, network, database, Redis, volumes, secrets, and ports:
| Component | Stable | Development |
|---|---|---|
| Application | helprr on 3050 |
helprr-dev on 3051 |
| PostgreSQL | helprr-db |
helprr-dev-db, loopback port 5433 |
| Redis | helprr-redis |
helprr-dev-redis, loopback port 6380 |
| Database | helprr |
helprr_dev |
| Volumes/network | Stable names | Dedicated helprr-dev-* names |
Generate the development-only env file. The helper refuses to overwrite an existing
.env.dev; do not copy the production database, Redis, JWT, or VAPID secrets:
./scripts/setup-env.sh --dev
nano .env.devBuild the current checkout in the isolated stack:
HELPRR_DEV_GIT_SHA="$(git rev-parse --short HEAD)" \
docker compose --env-file .env.dev -f docker-compose.dev.yml \
up -d --buildOpen http://YOUR_SERVER:3051. The stable installation on port 3050 remains
running and its database is never mounted or addressed by the development stack.
To exercise the image published from development, set this in .env.dev:
HELPRR_DEV_IMAGE=ghcr.io/saibarathr/helprr:edgeBefore testing a migration or replacing the development image, create a backup of only the isolated development database. Development and stable dumps are written to separate private directories. Then pull and replace only the development app:
./scripts/backup.sh --dev
docker compose --env-file .env.dev -f docker-compose.dev.yml pull helprr-dev
docker compose --env-file .env.dev -f docker-compose.dev.yml \
up -d --no-build --no-deps helprr-dev
curl -fsS http://localhost:3051/api/health
curl -fsS http://localhost:3051/api/readyThe app replacement must not restart helprr-dev-db or helprr-dev-redis. Readiness
must report the development database, Redis, and migrations as ok.
See Maintainer development and release workflow
for the complete feature, edge, release, promotion, rollback, and hotfix process.
- Docker itself does not provide TLS. Put Helprr behind an HTTPS reverse proxy before relying on PWA installation or Web Push from a non-localhost address.
- Set
TRUST_FORWARDED_PROTO=trueonly when that proxy strips and sets forwarded headers itself. This enables correct secure-cookie and client-IP decisions. - Set
APP_ORIGIN=https://helprr.example.comwhen enabling AniList OAuth in production. It must be a valid HTTPS origin. - If the PostgreSQL password contains URL-reserved characters (
@,:,/,?,#, …), setDATABASE_URLexplicitly with the password percent-encoded. - The VAPID keys are runtime configuration: after adding or rotating them, run
docker compose up -d --no-build --no-deps helprr— no rebuild or data-service restart is needed. Already-subscribed devices re-subscribe automatically on their next endpoint rotation, or manually from Settings → Notifications.
Use Node.js 24 to match the Docker image, plus Docker Compose for the local PostgreSQL and Redis services.
- Create Compose configuration and start only the data services. Compose reads the project-level
.env, not.env.local.
cp .env.example .env
# Set POSTGRES_PASSWORD and REDIS_PASSWORD in .env first
docker compose up -d helprr-db helprr-redis- Create
.env.localfor the Node process. Use host addresses—not Compose service names—and URL-encode the PostgreSQL password if needed.
DATABASE_URL=postgresql://postgres:YOUR_ENCODED_POSTGRES_PASSWORD@localhost:5432/helprr
REDIS_URL=redis://localhost:6379
REDIS_PASSWORD=YOUR_REDIS_PASSWORD
APP_PASSWORD=YOUR_BOOTSTRAP_ADMIN_PASSWORD
JWT_SECRET=YOUR_32_OR_MORE_CHARACTER_SECRET
TZ=Etc/UTC- Install dependencies, initialize Prisma, and run the app.
npm ci
npm run db:generate
npm run db:deploy
npm run devThe two database commands explicitly load .env.local and stop if that file is
missing; Prisma otherwise auto-loads .env, which may describe a different Compose
stack. .env.dev is only the isolated Compose interpolation file and intentionally
does not contain DATABASE_URL. Open http://localhost:3050.
Use npm run db:migrate only when you are authoring a new Prisma migration; it is not
the normal first-run command.
Copy .env.example as a starting point. Never commit .env, .env.local, API keys, passwords, VAPID private keys, or backups containing credentials.
At startup, Helprr validates the required PostgreSQL, Redis, and session-signing
configuration before any polling or cleanup work begins. Missing, malformed, or
shipped example/change-me credentials stop startup with one redacted error that
names the affected variables without printing their values. APP_PASSWORD is
also checked when supplied, but remains optional after the bootstrap admin has a
stored password unless HELPRR_ADMIN_PASSWORD_RESET=true.
| Variable | Docker Compose / local | Purpose and guidance |
|---|---|---|
POSTGRES_PASSWORD |
Required by Compose; not used by a Node-only app | Password for the bundled PostgreSQL container. It is used to form Compose's default DATABASE_URL. |
DATABASE_URL |
Required by the app | PostgreSQL Prisma connection string. In Compose it is optional if the bundled default is suitable; explicitly set it for an external database or a percent-encoded password. |
REDIS_URL |
Required by the app | Redis connection URL. Use redis://helprr-redis:6379 inside Compose and redis://localhost:6379 for a host-run Node process. |
REDIS_PASSWORD |
Required by the app and Compose | Redis AUTH password. Compose starts Redis with this password. |
APP_PASSWORD |
Needed to create/recover the bootstrap admin | Seeds the bootstrap admin only. It is never used as the normal live login password after that account has a stored hash. |
JWT_SECRET |
Required by the app | Session-signing secret; must be at least 32 characters. Generate with openssl rand -base64 48. |
| Variable | Default | When to use it |
|---|---|---|
HELPRR_ADMIN_USERNAME |
admin |
Changes the bootstrap admin's username. |
HELPRR_ADMIN_PASSWORD_RESET |
off | Set to true for one restart to reset the bootstrap admin from APP_PASSWORD; remove it immediately after recovery. It does not revoke existing sessions. |
TZ |
UTC when invalid or absent |
IANA timezone used for application date/time behavior, for example Asia/Kolkata. |
LOG_DIR |
app logs directory; /app/logs in Docker |
Location for server logs. Compose persists its default through the helprr-logs volume. |
APP_ORIGIN |
none | Required for AniList OAuth in production. Use the public HTTPS origin, such as https://helprr.example.com. |
TRUST_FORWARDED_PROTO |
off | Set to true only behind a trusted proxy that sanitizes X-Forwarded-*; enables secure cookies and forwarded client-IP rate limiting. |
HELPRR_CUSTOM_HEADERS |
off | Set to true to expose per-connection custom HTTP headers for supported services behind an authenticating proxy (for example, Authelia or Cloudflare Access). |
EXTRA_ALLOWED_IMAGE_HOSTS |
none | Comma-separated trusted external image hosts to permit through the image proxy. Do not add private/internal hosts. |
| Variable | Purpose |
|---|---|
VAPID_SUBJECT |
Contact URI supplied to push providers, for example mailto:you@example.com. |
VAPID_PUBLIC_KEY |
Public VAPID key served to browsers at runtime (the old NEXT_PUBLIC_VAPID_PUBLIC_KEY name is still accepted). |
VAPID_PRIVATE_KEY |
Server-only VAPID private key. Keep it secret. |
Generate a pair with:
npx web-push generate-vapid-keysWithout a complete VAPID set, Helprr still runs but push notification subscription/delivery is unavailable.
All values below are optional positive integers; invalid or non-positive values fall back to the defaults.
| Variable | Default | Scenario |
|---|---|---|
IMAGE_CACHE_DIR |
/tmp/helprr-image-cache |
Directory for server-side cached image bytes. Choose a writable, persistent path only if you provision one. |
IMAGE_CACHE_TTL_SECONDS |
604800 (7 days) |
How long a successful image is considered fresh. |
IMAGE_CACHE_STALE_SECONDS |
2592000 (30 days) |
How long a stale cached image may be served when its upstream fails. |
IMAGE_UPSTREAM_FETCH_TIMEOUT_MS |
5000 |
Timeout for fetching an upstream image. |
TMDB_CACHE_DEFAULT_TTL_SECONDS |
600 (10 minutes) |
Default TTL for TMDb data without a more specific category. |
TMDB_CACHE_DISCOVER_TTL_SECONDS |
600 (10 minutes) |
TTL for TMDb discovery responses. |
TMDB_CACHE_DETAILS_TTL_SECONDS |
86400 (1 day) |
TTL for TMDb title/detail responses. |
TMDB_CACHE_STATIC_TTL_SECONDS |
604800 (7 days) |
TTL for TMDb static/reference data. |
TMDB_CACHE_STALE_SECONDS |
2592000 (30 days) |
Stale-if-error window for TMDb cache data. |
CACHE_LOCK_TTL_MS |
10000 |
Cache-fill lock duration; change only when diagnosing unusually slow or long-running upstream requests. |
The bundled Compose file now passes these advanced values through when they are set in .env. The default image-cache directory is inside the app container, so it is ephemeral if that container is recreated unless you add your own persistent mount.
- Sign in with the bootstrap administrator.
- Open Settings → Instances and connect the services you actually use. Test each connection before relying on it.
- In Settings → Users, create member accounts and grant only the capabilities they need.
- Configure preferences, dashboard layout, notifications, and optional cleanup/bandwidth rules.
- For push: serve the app over HTTPS, configure VAPID values, open Helprr on the target device, install it as a PWA if desired, and allow notifications.
- Export a backup from Settings → Backup & Restore after the initial configuration and keep it secure.
Prisma migrations are the database source of truth.
- For normal deployment and first setup, use
npm run db:deploy; the Docker entrypoint runs the sameprisma migrate deploycommand automatically before starting Next.js. - When changing
prisma/schema.prismaduring development, runnpm run db:migrateand commit the generated migration directory. - Never edit or remove a migration after it has shipped in a release. Add a new migration instead.
- Patch releases must not contain destructive schema changes. Changes that drop or rewrite user data require explicit migration and rollback guidance in a minor or major release.
- A database created by an older
prisma db pushworkflow with no migration history must be baselined once before Docker can start it:docker compose run --rm helprr ./node_modules/.bin/prisma migrate resolve --applied 0001_init docker compose up -d
Tagged releases contain docker-compose.yml, env.example, setup-env.sh, and
backup.sh. This lets an installation created without Git update without cloning
the repository. To install an exact vX.Y.Z release from the existing Helprr
directory, fetch the backup helper first and create a validated backup:
mkdir -p scripts
HELPRR_RELEASE=vX.Y.Z
HELPRR_ASSET_BASE="https://github.com/SaiBarathR/helprr/releases/download/$HELPRR_RELEASE"
curl -fsSL -o scripts/backup.sh "$HELPRR_ASSET_BASE/backup.sh"
chmod 700 scripts/backup.sh
./scripts/backup.shOnly after that succeeds, replace the non-secret deployment files and helper scripts,
review the new .env.example against the existing .env, select the matching exact
image version in .env (without the leading v), then pull and restart:
curl -fsSL -o docker-compose.yml "$HELPRR_ASSET_BASE/docker-compose.yml"
curl -fsSL -o .env.example "$HELPRR_ASSET_BASE/env.example"
curl -fsSL -o scripts/setup-env.sh "$HELPRR_ASSET_BASE/setup-env.sh"
curl -fsSL -o scripts/backup.sh "$HELPRR_ASSET_BASE/backup.sh"
chmod 700 scripts/setup-env.sh scripts/backup.sh
# Set HELPRR_VERSION=X.Y.Z in .env after reviewing the release notes.
docker compose pull helprr
docker compose up -d --no-build --no-deps helprr
docker compose ps helprr
curl -fsS http://localhost:3050/api/health
curl -fsS http://localhost:3050/api/readyThe helper keeps Helprr online while pg_dump takes a consistent snapshot, verifies
that pg_restore can read the completed custom-format archive, and atomically writes
it under backups/stable/ with private permissions. If backup creation or validation
fails, the update commands must not be run.
Pending database migrations run automatically before the app starts. The
container drains background work gracefully on replacement (bounded at 30
seconds), so updating while downloads or cleanup are active is safe. The scoped
--no-deps helprr command leaves PostgreSQL and Redis running during the update.
To stay on an exact version instead of a channel, set HELPRR_VERSION in
.env (for example HELPRR_VERSION=1.0.0) and re-run the two Docker commands
to move between versions. Downgrading across releases is not supported once a
newer version has applied its migrations — restore the matching backup instead.
Admins see a notice on Settings and Settings → Service status when a newer stable Helprr release is available. The server checks Helprr's public GitHub latest- release endpoint on an admin visit and caches the result for six hours. It sends no installation data and never pulls an image, changes a tag, restarts a container, or applies an update. Back up and follow the normal update procedure after reviewing the linked release notes.
Settings → Service status → Support bundle downloads bounded JSON diagnostics: the running version/commit, readiness, migration names, aggregate database counts, non-secret runtime settings, configured service types/presence flags, and up to 250 recent log entries. The bundle never includes service URLs, API/OAuth tokens, custom- header values, password hashes, database/Redis credentials, user records, or media and request rows. Known current credentials, sensitive structured fields, embedded URL or Basic-auth credentials, and long token-shaped historical values are redacted again at download time. If Helprr cannot load the service-credential inventory, it omits logs instead of weakening redaction.
The remaining service labels, aggregate counts, versions, and redacted log messages can still describe your installation. Review the JSON and treat it as private diagnostic data before sharing it.
Everything Helprr needs to recover lives in PostgreSQL. Redis holds only cache and login rate-limit state and never needs to be backed up. The in-app settings export (Settings → Backup) is a portable subset — connections, preferences, rules, watchlists — useful for moving settings between installs, but it is not a disaster-recovery backup: it does not contain users' password hashes, sessions, push subscriptions, or history.
Back up (run before every upgrade and on a schedule):
./scripts/backup.shThe no-clone quick start installs this helper under scripts/ with mode 0700.
If it is missing from an older installation, download backup.sh from the exact
target release as shown in Updating before changing Compose or pulling an image.
Stable backups default to backups/stable/. Use
./scripts/backup.sh --output-dir /path/to/protected/storage for a different local or
mounted destination. Use ./scripts/backup.sh --dev only for the standalone
development stack; it explicitly selects .env.dev, docker-compose.dev.yml, and
helprr-dev-db and defaults to backups/development/. The helper never stops,
restarts, updates, or migrates containers and never overwrites an existing dump.
Warning
Dumps contain your service API keys and users' password hashes. Treat backup files as secrets: restrict permissions and encrypt them wherever they are stored. Archive validation catches malformed or truncated output at creation time, but it is not a restore test. Periodically restore into an isolated environment and retain an off-host copy according to your own recovery needs.
Restore over an existing installation (e.g. roll back after a bad change):
docker compose stop helprr
docker compose exec -T helprr-db pg_restore -U postgres --clean --if-exists -d helprr < backups/stable/helprr-pre-upgrade-YYYYMMDD-HHMMSS.dump
docker compose start helprrRestore onto a fresh host (disaster recovery):
# 1. Set up the deployment files and .env as in the quick start. Reuse the old
# install's JWT_SECRET (or sessions are invalidated), VAPID keys (or devices
# must re-subscribe), and HELPRR_ADMIN_USERNAME — on boot the bootstrap
# admin is renamed to that value (default "admin"). Passwords are safe
# either way: APP_PASSWORD never overwrites an existing password hash.
docker compose up -d helprr-db
docker compose exec -T helprr-db pg_restore -U postgres --clean --if-exists -d helprr < backups/stable/helprr-pre-upgrade-YYYYMMDD-HHMMSS.dump
docker compose up -dThe restored database already contains the applied-migrations history, so the app boots without re-running old migrations. Restore with the same or newer Helprr version than the one that produced the dump.
Helprr runs a bounded retention sweep once per day. Notification history uses the value configured in Settings → Notifications. Cleanup history and settled scheduled-alert occurrences are kept for 90 days, operation-audit records for 365 days, and expired session rows are removed after the fixed 30-day login-token lifetime. Pending alerts and pending Seerr approvals are live state and are not removed by history retention.
The same sweep removes image-cache files that have had no Redis metadata for at least 24 hours, temporary image files older than one hour, and cache-generation directories abandoned for at least 24 hours. It reads Redis successfully and re-checks the active generation before touching files; if Redis is unavailable or an admin cache purge races the sweep, filesystem cleanup fails closed and waits for a later run. Log files continue to use the separate retention value in Settings → Logging. Database backups are never removed by Helprr retention.
docker compose down # stops and removes containers; your data volumes remain
docker compose down -v # ⚠ ALSO DELETES the database, Redis, and log volumes
docker image rm ghcr.io/saibarathr/helprr:stable # or your pinned :X.Y.Z tagCaution
docker compose down -v permanently deletes all application data — every
user, connection, watchlist, and history row. There is no undo. Take a
backup first unless you truly mean it.
For clarity, these are the places where Helprr can remove files from your disk. All are permission-gated. Manual file/media/torrent/queue actions write success or failure to Settings → Operation audit; cleaner actions retain their reconciled per-item outcomes in Cleanup → History. Operation-audit records are retained for 365 days and cleanup history for 90 days:
- Cleanup (queue, download, and seeding rules) — can remove downloads from qBittorrent including their files when a rule says so. Disabled by default; supports dry-run previews, and automatic mode is opt-in per rule.
- Delete movie / series / artist / album — each has an optional "also delete files" choice in its confirmation dialog (off by default).
- Delete episode file / track file / movie file — deletes that file from disk; the media item stays in the library as missing.
- Activity queue removal — optionally removes the download (and its data) from the download client.
- Torrent deletion — optionally deletes the torrent's data from disk.
- Manual import — moves or copies files into your library folders.
If Sonarr/Radarr has a recycle bin configured, *arr file deletions go there instead of being removed outright — Helprr records whether that was the case in the operation-audit entry.
# App
npm run dev
npm run build
npm run lint
# Prisma
npm run db:generate
npm run db:deploy
npm run db:migrate
# Docker (published image)
docker compose pull
docker compose up -d
docker compose logs -f helprr
docker compose down
# Docker (isolated development stack built from source)
docker compose --env-file .env.dev -f docker-compose.dev.yml up -d --build
# Docker (published edge image; set HELPRR_DEV_IMAGE=...:edge in .env.dev first)
docker compose --env-file .env.dev -f docker-compose.dev.yml pull helprr-dev
docker compose --env-file .env.dev -f docker-compose.dev.yml \
up -d --no-build --no-deps helprr-dev- Use unique, long secrets and a private network or HTTPS reverse proxy. Do not expose Helprr directly to the public internet without understanding the security implications.
- Passwords are stored as per-user scrypt hashes.
APP_PASSWORDseeds/resets only the bootstrap admin; it is not a universal login password. - Resetting the bootstrap password does not invalidate active sessions. Revoke sessions from Settings → Sessions when access needs to be removed.
- Service credentials and custom headers are sensitive. Restrict administrator accounts and protect backups/log exports.
- Verify AI-generated changes before deploying them. Keep your service containers and this project up to date, and test upgrades against a backup.
- Found a vulnerability? Please report it privately — see SECURITY.md.
Helprr is free software, licensed under the GNU General Public License v3.0. Release history lives in CHANGELOG.md.

























