This guide walks you through the fastest path to a working Riven installation: a Docker Compose stack running the Riven backend, a PostgreSQL database, and Jellyfin (or Plex) — all talking through a shared FUSE mount. By the end you will have a live web UI atDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/rivenmedia/riven/llms.txt
Use this file to discover all available pages before exploring further.
http://localhost:8080 and your first content request in the pipeline.
Prerequisites
Before you begin, make sure you have the following:- Docker and Docker Compose (v2) installed on a Linux host.
- An active debrid account — Real-Debrid or AllDebrid. Riven requires a debrid service to cache and stream torrent content.
- A media server — Plex, Jellyfin, or Emby — either already running or set up alongside Riven in the same Compose stack.
- The FUSE kernel module loaded on the host (
sudo modprobe fuse).
Riven’s RivenVFS uses FUSE to expose a virtual mount point. The host must have
/dev/fuse available and the SYS_ADMIN capability must be granted to the Riven container.Steps
Pick a path on your host that Riven will use as its FUSE mount point. This guide uses
/opt/riven/mount. Create it and make it a shared bind mount — this is required so that mount propagation works correctly between the Riven container and your media server container.sudo mkdir -p /opt/riven/data
sudo mkdir -p /opt/riven/mount
sudo mkdir -p /opt/riven/db
# Turn the mount directory into a bind mount and mark it shared (run once per boot)
sudo mount --bind /opt/riven/mount /opt/riven/mount
sudo mount --make-rshared /opt/riven/mount
# Verify the propagation flag is set
findmnt -T /opt/riven/mount -o TARGET,PROPAGATION
# Expected output: PROPAGATION = shared or rshared
The
mount --bind and mount --make-rshared commands must be re-run after every host reboot unless you automate them. See the Installation guide for systemd unit and fstab options.Create a
docker-compose.yml file and paste in the contents below. Replace every /path/to/riven/* path with the directories you created in the previous step (e.g. /opt/riven/data, /opt/riven/mount, /opt/riven/db).services:
riven:
image: spoked/riven:latest
container_name: riven
restart: unless-stopped
ports:
- "8080:8080"
tty: true
cap_add:
- SYS_ADMIN
security_opt:
- apparmor:unconfined
shm_size: 1024m
devices:
- /dev/fuse
environment:
- PUID=1000
- PGID=1000
- TZ=America/New_York
- RIVEN_FORCE_ENV=true
- RIVEN_DATABASE_HOST=postgresql+psycopg2://postgres:postgres@riven-db/riven
healthcheck:
test: curl -s http://localhost:8080 >/dev/null || exit 1
interval: 30s
timeout: 10s
retries: 10
volumes:
- /path/to/riven/data:/riven/data
- /path/to/riven/mount:/mount:rshared,z
depends_on:
riven_postgres:
condition: service_healthy
riven_postgres:
image: postgres:17-alpine
container_name: riven-db
environment:
- PGDATA=/var/lib/postgresql/data/pgdata
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
- POSTGRES_DB=riven
volumes:
- /path/to/riven/db:/var/lib/postgresql/data/pgdata
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
jellyfin:
image: jellyfin/jellyfin
container_name: jellyfin
user: 1000:1000
restart: unless-stopped
ports:
- "8096:8096"
volumes:
- /path/to/jellyfin/config:/config
- /path/to/riven/mount:/mount:rslave,z
Notice that the Jellyfin container mounts the same host path (
/path/to/riven/mount) with :rslave,z propagation. This ensures Jellyfin automatically sees any FUSE mounts that RivenVFS creates inside the Riven container without requiring a Jellyfin restart.If you use Plex instead of Jellyfin, add your Plex container to the same Compose file and mount the path with
:rslave,z as shown. Make sure your Plex libraries point to /mount/movies, /mount/shows, etc. (the container-internal path, not the host path).Docker will pull the images, initialise the PostgreSQL database, and start the Riven backend. Riven waits for PostgreSQL to be healthy before starting, so the first boot may take 30–60 seconds.
Riven serves its API on port
8080 (configured via the --port CLI argument, default 8080). You can verify the backend is ready by hitting the health endpoint:curl http://localhost:8080/api/v1/health
# Returns: {"message": "True"} when Riven has fully initialised
Open http://localhost:8080 in your browser. The Riven web UI loads automatically.
Real-Debrid
- Go to real-debrid.com/apitoken and copy your API token.
- In the Riven UI, open Settings → Downloaders → Real-Debrid.
- Toggle Enabled on and paste the token into the API Key field.
- Save settings.
AllDebrid
- Log in to AllDebrid and generate an API key from your account settings.
- In the Riven UI, open Settings → Downloaders → AllDebrid.
- Toggle Enabled on and paste the key into the API Key field.
- Save settings.
With a debrid provider connected, enable at least one content source so Riven knows what to download.
Overseerr
- In the Riven UI, open Settings → Content → Overseerr.
- Toggle Enabled on.
- Enter your Overseerr URL (e.g.
http://localhost:5055) and API key. - Save settings.
- Open Overseerr and submit a movie or TV show request. Riven will pick it up on the next poll cycle and begin scraping, ranking, and downloading.
Plex Watchlist
- In the Riven UI, open Settings → Content → Plex Watchlist.
- Toggle Enabled on.
- Provide your Plex token.
- Save settings.
- Add an item to your Plex Watchlist; Riven will detect it automatically.
Trakt
- In the Riven UI, open Settings → Content → Trakt.
- Toggle Enabled on and follow the OAuth flow to connect your Trakt account.
- Save settings. Items from your Trakt watchlist will begin syncing.
Next steps
Installation reference
Full environment variable reference, persistent mount setup, and production hardening tips.
Configuration overview
Configure scrapers, torrent ranking, library profiles, and VFS naming templates.