Skip to content

henry40408/rdrs

Repository files navigation

RDRS - RSS Reader in Rust

CI codecov License Rust Docker Casual Maintenance Intended

A self-hosted RSS/Atom feed reader built with Rust. Privacy-focused, lightweight, and designed for personal use.

Light Dark
Unread list - Light Unread list - Dark
Keyboard shortcuts - Light Keyboard shortcuts - Dark

Features

  • Feed Management - Subscribe to RSS/Atom feeds, organize into categories, OPML import/export
  • Reading Experience - Mark read/unread, star entries, full-text search, keyboard shortcuts
  • Privacy Protection - HTML sanitization, tracking URL removal, image proxy
  • Full Content Extraction - Fetch complete article content using readability algorithm
  • AI Summarization - Automatic article summaries via Kagi AI integration
  • WebAuthn/Passkey - Passwordless authentication with passkey support
  • External Services - Save entries to Linkding bookmark manager
  • Google Reader API - Compatible with GReader clients (FeedMe, Read You, etc.)
  • Multi-User Support - Role-based access control with admin panel
  • Docker Ready - Single-binary deployment with all assets embedded, multi-platform container images

Quick Start

Using Docker (Recommended)

docker run -d \
  --name rdrs \
  -p 3000:3000 \
  -v rdrs_data:/data \
  -e SIGNUP_ENABLED=true \
  ghcr.io/henry40408/rdrs:latest

Visit http://localhost:3000 and create your account.

Building from Source

# Clone repository
git clone https://github.com/henry40408/rdrs.git
cd rdrs

# Build release binary
cargo build --release

# Run server
./target/release/rdrs

Configuration

All configuration is done via environment variables:

Variable Default Description
DATABASE_URL rdrs.sqlite3 SQLite database file path
SERVER_PORT 3000 HTTP server port
SIGNUP_ENABLED false Allow new user registration
MULTI_USER_ENABLED false Allow multiple users (requires signup enabled)
IMAGE_PROXY_SECRET Auto-generated HMAC secret for secure image proxying
PUBLIC_BASE_URL - Public base URL for generating absolute image proxy URLs in API responses (e.g., https://rdrs.example.com). If not set, relative paths are used (backward compatible).
USER_AGENT RDRS/... Custom user agent for feed fetching
WEBAUTHN_RP_ID localhost WebAuthn Relying Party ID for passkey authentication
WEBAUTHN_RP_ORIGIN http://localhost:{port} WebAuthn Relying Party origin URL
WEBAUTHN_RP_NAME rdrs WebAuthn Relying Party display name
RUST_LOG - Log level filter (e.g., info, debug, rdrs=debug)

Usage

Adding Feeds

  1. Navigate to the Feeds page
  2. Enter the feed URL (RSS/Atom feed or webpage with feed link)
  3. RDRS will auto-discover the feed and fetch metadata

Keyboard Shortcuts

The interface supports vim-style keyboard navigation for efficient reading.

OPML Import/Export

  • Export: Download all your feeds as an OPML file from Settings
  • Import: Upload an OPML file to bulk-add feeds

Linkding Integration

Connect RDRS to your Linkding instance to save articles for later:

  1. Go to User Settings
  2. Enter your Linkding URL and API token
  3. Use the "Save" button on any entry

Docker

Docker Compose

services:
  rdrs:
    image: ghcr.io/henry40408/rdrs:latest
    ports:
      - "3000:3000"
    volumes:
      - rdrs_data:/data
    environment:
      - SIGNUP_ENABLED=true
      - IMAGE_PROXY_SECRET=your-secret-here
    restart: unless-stopped

volumes:
  rdrs_data:

Building Docker Image

docker build -t rdrs:latest .

The Dockerfile uses multi-stage builds with a distroless base image for minimal size and attack surface.

Development

Prerequisites

  • Rust 1.92+
  • SQLite (bundled via rusqlite)

Running Tests

cargo test

Project Structure

See ARCHITECTURE.md for detailed architecture documentation.

Tech Stack

  • Web Framework: Axum 0.8
  • Async Runtime: Tokio
  • Database: SQLite (rusqlite)
  • Templates: Askama
  • Feed Parsing: feed-rs
  • HTML Sanitization: Ammonia
  • Content Extraction: Readability

License

MIT