← All articles
Code is displayed on a computer screen.

Ryot: Self-Hosted Media Tracking for Movies, Books, Games, and More

Media 2026-02-15 · 9 min read ryot media-tracker self-hosted movies books fitness
By Selfhosted Guides Editorial TeamSelf-hosting practitioners covering open source software, home lab infrastructure, and data sovereignty.

Tracking what you watch, read, play, and listen to across multiple platforms is a fragmented experience. Your movie history lives in Letterboxd, your reading list in Goodreads, your game backlog in a spreadsheet, and your podcast queue in whatever app you're using this month. Each platform has its own login, its own data format, and its own terms of service governing your data.

Photo by Rob Wingate on Unsplash

Ryot (Roll Your Own Tracker) is a self-hosted media tracker that consolidates all of this into a single application. Track movies, TV shows, anime, manga, books, audiobooks, podcasts, video games, visual novels, and even workouts -- all in one place, on your own server. Your data stays yours, and you're not locked into any platform's ecosystem.

Ryot media tracker logo

What Ryot Tracks

Unlike specialized tools that focus on one media type, Ryot is a unified tracker across multiple categories:

Each media type pulls metadata from its respective source automatically. When you add a movie, Ryot fetches the poster, synopsis, cast, runtime, and release date from TMDB. When you add a book, it pulls the cover, author, page count, and description from OpenLibrary.

Why Self-Host Your Media Tracking

Commercial tracking services have a few problems that self-hosting solves:

Data ownership

Letterboxd, Goodreads, and MyAnimeList all hold your tracking data hostage. If the service shuts down, changes its API, or decides to monetize your data differently, you lose years of carefully maintained lists. With Ryot, your data lives in a PostgreSQL database on your server that you can back up, export, and query however you want.

Privacy

Commercial trackers build profiles of your media consumption habits. What you watch, when you watch it, how quickly you binge a series -- this is valuable behavioral data. Ryot runs locally and doesn't phone home.

Consolidation

Instead of maintaining accounts on five different platforms, you have one interface for everything. Your "currently consuming" list spans movies, books, games, and podcasts in a single view.

Customization

Rate media on whatever scale you want. Add custom metadata fields. Create collections that span media types (e.g., "Cyberpunk" containing movies, books, games, and anime). No platform tells you how to organize your data.

Ryot vs. Other Tracking Tools

Ryot occupies a unique niche -- it's a multi-media tracker rather than a single-purpose tool.

Feature Ryot Tautulli Overseerr Bookwyrm Stump
Movies/TV Yes Plex stats only Request mgmt No No
Books Yes No No Yes (social) No
Video games Yes No No No No
Podcasts Yes No No No No
Anime/manga Yes No No No No
Workouts Yes No No No No
Comics/manga reader No No No No Yes
Plex integration Yes (import) Native Native No No
Social features Limited No No Fediverse No
Self-hosted Yes Yes Yes Yes Yes
Multi-user Yes Yes Yes Yes Yes
API GraphQL REST REST ActivityPub REST

When to pick Ryot

When to pick alternatives

Ryot doesn't replace any of these tools -- it complements them. You might use Tautulli for Plex analytics, Overseerr for media requests, and Ryot for personal tracking across all media types.

Like what you're reading? Subscribe to Self-Hosted Weekly — free weekly guides in your inbox.

Self-Hosting Ryot: Docker Compose Setup

Ryot requires PostgreSQL as its database backend. Here's a complete Docker Compose configuration:

# docker-compose.yml
services:
  ryot:
    image: ghcr.io/ignisda/ryot:latest
    container_name: ryot
    ports:
      - "8000:8000"
    environment:
      # Database connection
      DATABASE_URL: postgres://ryot:your-secure-password@ryot-db:5432/ryot

      # Server configuration
      SERVER_INSECURE_COOKIE: "false"
      # Set to "true" if not using HTTPS (development only)

      # TMDB API key for movie/TV metadata
      MOVIES_TMDB_ACCESS_TOKEN: "your-tmdb-read-access-token"

      # IGDB credentials for video game metadata
      VIDEO_GAMES_TWITCH_CLIENT_ID: "your-twitch-client-id"
      VIDEO_GAMES_TWITCH_CLIENT_SECRET: "your-twitch-client-secret"

      # Audible locale for audiobook metadata
      AUDIO_BOOKS_AUDIBLE_LOCALE: "us"

      # Optional: configure timezone
      TZ: "America/New_York"
    volumes:
      - ryot-data:/data
    depends_on:
      ryot-db:
        condition: service_healthy
    restart: unless-stopped

  ryot-db:
    image: postgres:16-alpine
    container_name: ryot-db
    environment:
      POSTGRES_USER: ryot
      POSTGRES_PASSWORD: your-secure-password
      POSTGRES_DB: ryot
    volumes:
      - ryot-postgres:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ryot"]
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped

volumes:
  ryot-data:
  ryot-postgres:

Getting API keys

Ryot uses external APIs for metadata. Here's how to get the keys:

TMDB (movies and TV shows):

  1. Create an account at themoviedb.org
  2. Go to Settings > API > Create > Developer
  3. Copy the "Read Access Token" (not the API Key)

IGDB/Twitch (video games):

  1. Create a Twitch developer account at dev.twitch.tv
  2. Register a new application
  3. Copy the Client ID and generate a Client Secret

Other metadata sources (OpenLibrary, Anilist, iTunes podcast index) don't require API keys -- Ryot uses their public APIs.

Starting Ryot

docker compose up -d

Access the web interface at http://your-server:8000. The default credentials are:

Change these immediately after first login.

Reverse proxy configuration

For production use, put Ryot behind a reverse proxy with HTTPS. Here's a Caddy example:

ryot.yourdomain.com {
    reverse_proxy ryot:8000
}

Or with Nginx:

server {
    listen 443 ssl;
    server_name ryot.yourdomain.com;

    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;

    location / {
        proxy_pass http://localhost:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Importing Existing Data

One of Ryot's strongest features is its import system. You don't have to start from scratch -- bring your tracking history from other platforms.

Supported import sources

Source Media types Import format
Goodreads Books CSV export
Letterboxd Movies CSV export
IMDB Movies, TV CSV export
MyAnimeList Anime, manga XML export
Trakt Movies, TV API (OAuth)
Audiobookshelf Audiobooks API
MediaTracker All types JSON export
Movary Movies JSON export
StoryGraph Books CSV export
Plex Movies, TV Watchlist
Jellyfin Movies, TV API
Generic JSON Any Custom JSON

Import process

  1. Navigate to Settings > Imports in the Ryot dashboard
  2. Select your source platform
  3. Upload the export file or provide API credentials
  4. Ryot matches items against its metadata sources and imports your ratings, reviews, and progress

For Trakt imports, you'll authenticate via OAuth and Ryot pulls your entire watch history. For Goodreads, export your library as CSV from Goodreads settings and upload it directly.

Handling import conflicts

When importing from multiple sources, duplicates are detected by matching against metadata IDs. If you've tracked the same movie in both Letterboxd and Trakt, Ryot merges the data -- keeping the most recent rating and combining watch dates.

Using Ryot Day-to-Day

Adding media

The search function works across all media types simultaneously. Type "Dune" and you'll see the movie, the book, the video game, and the TV series all in one result set. Select the one you want and mark it as:

Rating and reviewing

Ryot supports customizable rating scales:

You can write text reviews, which are stored locally and can optionally be shared if you enable social features.

Collections

Create custom collections that span media types. Examples:

Progress tracking

For long-form media, Ryot tracks granular progress:

Workout tracking

Ryot includes a workout tracker, which is an unusual feature for a media tracker. You can log:

This isn't as feature-rich as a dedicated fitness app, but it's convenient if you want all your tracking in one place.

GraphQL API

Ryot exposes a full GraphQL API, which opens up automation and integration possibilities.

Authentication

# Get an auth token
curl -X POST http://ryot:8000/backend/graphql \
  -H "Content-Type: application/json" \
  -d '{
    "query": "mutation { loginUser(input: { username: \"admin\", password: \"yourpassword\" }) { apiKey } }"
  }'

Querying your media

# Get all media currently in progress
query {
  mediaList(input: { lot: MOVIE, filter: { status: IN_PROGRESS } }) {
    items {
      title
      publishYear
      averageRating
    }
  }
}

Adding media via API

# Mark a movie as completed
mutation {
  commitMedia(input: {
    identifier: "693134"
    lot: MOVIE
    source: TMDB
  }) {
    id
  }
}

Integration ideas

Multi-User Setup

Ryot supports multiple users with separate libraries, ratings, and progress. Each user has:

This makes Ryot useful for households where multiple people want to track their media consumption independently.

User management

Create additional users from Settings > Users. Each user gets their own login and isolated data. There's no shared library concept -- if two users both track the same movie, they each have independent entries.

Sharing and social

Ryot has basic social features: users can follow each other and see what others are tracking (if privacy settings allow). This is optional and disabled by default.

Backup and Data Export

Database backup

Since all data lives in PostgreSQL, standard database backup practices apply:

# Dump the database
docker exec ryot-db pg_dump -U ryot ryot > ryot-backup.sql

# Automated daily backup with cron
0 3 * * * docker exec ryot-db pg_dump -U ryot ryot | gzip > /backups/ryot-$(date +\%Y\%m\%d).sql.gz

Data export

Ryot supports exporting your data in JSON format from the web interface. Navigate to Settings > Exports and download a full export. This includes all your media entries, ratings, reviews, progress, collections, and workout data.

The export format is documented, so you can write scripts to process or migrate your data if needed.

Performance and Resource Usage

Ryot is reasonably lightweight:

For large libraries (10,000+ items), the initial metadata fetch can take time, but day-to-day performance remains snappy.

Honest Trade-offs

Ryot is excellent if you:

Ryot has limitations:

The bottom line: If you've ever wished you could see your movies, books, games, and podcasts in one tracking interface without relying on five different commercial platforms, Ryot is exactly what you're looking for. The import system makes migration painless, the GraphQL API enables automation, and the multi-category approach means you'll actually use one tracker instead of maintaining several.

Get free weekly tips in your inbox. Subscribe to Self-Hosted Weekly