Getting Started
Install and run Riven TS with Docker.
Prerequisites
- Linux host with FUSE support and
/dev/fuseavailable - Docker Engine 24+ with Compose V2
- A debrid service account (Real-Debrid, AllDebrid, TorBox, …)
- A media server (Plex or Jellyfin)
- A TMDB API key (free at themoviedb.org)
Riven mounts its virtual file system with FUSE, which needs the SYS_ADMIN
capability and /dev/fuse. There is no way to run it without them.
Prefer to skip the manual setup? The Compose Generator produces the same files from a form. Prefer not to use Docker at all? See Running from Source.
Prepare the host mount
Riven mounts the VFS inside the container and shares it back to the host, which only works if the mount point uses shared propagation. A systemd unit is the most reliable way to guarantee this survives reboots:
[Unit]
Description=Make Riven data bind mount shared
After=local-fs.target
Before=docker.service
[Service]
Type=oneshot
ExecStart=/usr/bin/mount --bind /mnt/riven /mnt/riven
ExecStart=/usr/bin/mount --make-rshared /mnt/riven
RemainAfterExit=yes
[Install]
WantedBy=multi-user.targetsudo mkdir -p /mnt/riven
sudo systemctl daemon-reload
sudo systemctl enable --now riven-mount.service
findmnt -o TARGET,PROPAGATION /mnt/riven # must print "shared"Create the data directories
Riven writes logs and its generated ranking config to disk. The container runs as UID/GID 1000, so the directories must be owned by that user or Riven will fail to start:
mkdir -p logs data
sudo chown -R 1000:1000 logs dataCreate your docker-compose.yml
services:
riven:
image: ghcr.io/rivenmedia/riven-ts:main
container_name: riven
restart: unless-stopped
tty: true
cap_add:
- SYS_ADMIN
security_opt:
- apparmor:unconfined
devices:
- /dev/fuse
env_file: .env
ports:
- 3000:3000
volumes:
- ./logs:/app/logs
- ./data:/app/data
- /mnt/riven:/mount:rshared,z
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
postgres:
image: postgres:17-alpine
container_name: riven-postgres
restart: unless-stopped
environment:
POSTGRES_USER: riven
POSTGRES_PASSWORD: CHANGEME
POSTGRES_DB: riven
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U riven"]
interval: 5s
timeout: 5s
retries: 5
redis:
image: redis:8-alpine
container_name: riven-redis
restart: unless-stopped
command: redis-server --maxmemory-policy noeviction --appendonly yes
volumes:
- redis_data:/data
healthcheck:
test: ["CMD-SHELL", "redis-cli ping | grep PONG"]
interval: 5s
timeout: 5s
retries: 5
volumes:
postgres_data:
redis_data:There is no latest tag. Use :main to track the current build, or pin a
released version such as :1.2.3.
Create your .env file
# Core
RIVEN_SETTING__databaseUrl="postgres+psycopg2://riven:CHANGEME@postgres:5432/riven"
RIVEN_SETTING__redisUrl="redis://redis:6379"
# Must match the container-side path of the VFS volume above
RIVEN_SETTING__vfsMountPath="/mount"
# Bind the GraphQL API to all interfaces so it is reachable outside the
# container. It defaults to localhost, which is only useful for local runs.
RIVEN_SETTING__gqlHost="0.0.0.0"
# If you want to bind mount this file from the host, create it first;
# otherwise Docker will mount a directory named riven-ranking-config.json.
RIVEN_SETTING__rankingConfigPath="/app/data/riven-ranking-config.json"
RIVEN_SETTING__logLevel="info"
# Plugins to enable. tmdb and tvdb are always on and don't need listing.
RIVEN_SETTING__enabledPlugins=["seerr","stremthru","torrentio","plex"]
# Metadata (required)
RIVEN_PLUGIN_SETTING__REPO_PLUGIN_TMDB__apiKey="your-tmdb-api-key"
# Debrid store, via StremThru — set the key for the service you pay for
RIVEN_PLUGIN_SETTING__REPO_PLUGIN_STREMTHRU__realdebridApiKey="your-rd-key"
# Content source
RIVEN_PLUGIN_SETTING__REPO_PLUGIN_SEERR__url="http://seerr:5055"
RIVEN_PLUGIN_SETTING__REPO_PLUGIN_SEERR__apiKey="your-seerr-key"
# Media server
RIVEN_PLUGIN_SETTING__REPO_PLUGIN_PLEX__plexToken="your-plex-token"
RIVEN_PLUGIN_SETTING__REPO_PLUGIN_PLEX__plexServerUrl="http://plex:32400"See Configuration for every core setting, and Plugins for what each plugin accepts.
Start Riven
docker compose up -d
docker compose logs -f rivenRiven bootstraps, connects to PostgreSQL and Redis, registers its plugins, mounts the VFS, and serves the GraphQL API on port 3000. Confirm it is reachable:
curl -X POST http://localhost:3000 \
-H 'content-type: application/json' \
-d '{"query":"{ __typename }"}'Point your media server at the VFS
Add /mnt/riven as a library:
- Plex: Add Library → Movies/TV Shows → Browse for media folder
- Jellyfin: Dashboard → Libraries → Add Media Library
If the media server also runs in Docker, mount the same path with rslave
propagation — /mnt/riven:/mount:rslave,z — and set the plugin's
plexLibraryPath / jellyfinLibraryPath to the container-side path.
What's Next?
- Configure plugins for your content sources and services
- Production deployment for reverse proxies and updates
- Troubleshooting if something isn't working