Redlib

Redlib to otwartoźródłowy, alternatywny frontend do Reddita napisany w Rust (licencja AGPLv3). Powstał jako fork Libreddit, który przestał działać po zmianach w API Reddita w 2023 roku. Pobiera posty, komentarze i media po stronie serwera i serwuje własny, lekki interfejs: bez reklam, bez skryptów Reddita, bez ciasteczek śledzących i bez konta. Jest dla Reddita tym, czym Invidious dla YouTube, choć jest znacznie prostszy: jeden bezstanowy kontener, bez bazy danych i bez sekretów.

Redlib — subreddit r/selfhosted w jasnym motywie, układ kart

Interfejs obejmuje większość Reddita dostępnego bez logowania: feedy Home, Popular i All z pełnym sortowaniem, subreddity z paskiem bocznym i wiki, multireddity w adresie (/r/selfhosted+homelab+docker), profile użytkowników i wyszukiwarkę. Do wyboru są trzy układy listy (card, clean, compact) i kilkanaście motywów. Ścieżki są takie same jak na Reddicie, więc link reddit.com/r/... wystarczy przepisać na domenę instancji.

Redlib nie ma kont: przycisk Subscribe dopisuje subreddit do listy w ciasteczku przeglądarki, a Filter ukrywa subreddit we wszystkich feedach złożonych z wielu subredditów (Home, Popular, All, multireddity). Wszystkie ustawienia i subskrypcje leżą w ciasteczkach, a strona /settings pozwala przenieść je na inne urządzenie linkiem przywracania (/settings/restore/?...) albo przez eksport i import.

Architektura

Redlib nie przepisuje strony reddit.com, tylko sam rozmawia z API Reddita (oauth.reddit.com) i renderuje wynik z własnych szablonów. Na każde żądanie przeglądarki serwer pobiera JSON z API, składa z niego HTML i odsyła gotową stronę. Media również przechodzą przez instancję, pod ścieżkami na tej samej domenie:

Ścieżki, pod którymi Redlib przekazuje media z serwerów Reddita.
ŚcieżkaŹródło
/img/...Obrazy z i.redd.it
/preview/...Miniatury i podglądy z preview.redd.it
/hls/...Playlisty i segmenty wideo z v.redd.it

Architektura w sieci lokalnej

graph LR
    B[Przeglądarka] -->|HTTPS :443| T[Traefik<br/>lan-auth]
    T -->|HTTP :8080| R[redlib]
    R -->|"HTTPS, token aplikacji Android"| A[oauth.reddit.com<br/>API]
    R -->|HTTPS| M[i.redd.it<br/>preview.redd.it<br/>v.redd.it]

Ruch z przeglądarki przyjmuje Traefik , który terminuje TLS i przekazuje żądania do kontenera redlib w sieci proxy. Po drodze żądanie przechodzi przez middleware lan-auth. Integrację Traefika z uwierzytelnianiem opisuje wpis o Autheli .

Połączenie z Redditem

Otwarcie subreddita to jedno żądanie do Redlib, które po stronie serwera zamienia się w zapytanie do API Reddita. Miniatury przeglądarka pobiera potem także od Redlib:

sequenceDiagram
    participant B as Przeglądarka
    participant R as redlib
    participant A as API Reddita
    participant M as i.redd.it / preview.redd.it
    B->>R: /r/selfhosted
    R->>A: GET /r/selfhosted/hot (token OAuth)
    A-->>R: JSON z listą postów
    R-->>B: HTML z linkami /preview/... i /img/...
    loop każda miniatura
        B->>R: /preview/...
        R->>M: pobranie obrazu
        M-->>R: obraz
        R-->>B: obraz
    end

Przeglądarka nie łączy się z żadnym serwerem Reddita. Pilnuje tego nagłówek Content Security Policy, w którym domyślną regułą jest default-src 'none', a pozostałe źródła są ograniczone do samej instancji ('self', data:, blob:, np. img-src 'self' data:, connect-src 'self'), więc nawet zewnętrzny obraz albo skrypt w treści posta nie zostanie załadowany. Strona działa bez JavaScriptu. Wyjątkiem jest opcjonalny odtwarzacz HLS (hls.js, serwowany z instancji), bez którego filmy z Reddita grają bez dźwięku.

Reddit od 2023 roku mocno ogranicza anonimowy dostęp do API. Redlib omija to, podszywając się pod oficjalną aplikację na Androida: pobiera anonimowy token OAuth tak jak aplikacja, odświeża go co 24 godziny i wysyła te same nagłówki HTTP co oryginalny klient. Instancja nie potrzebuje więc klucza API ani konta, a Reddit widzi tylko publiczny adres IP łącza domowego i zapytania podpisane tokenem aplikacji, nie użytkownika.

Konfiguracja

docker-compose.yml

services:
  redlib:
    image: quay.io/redlib/redlib:latest
    container_name: redlib
    restart: unless-stopped
    user: nobody
    read_only: true
    cap_drop: [ALL]
    security_opt:
      - no-new-privileges:true
    environment:
      REDLIB_ROBOTS_DISABLE_INDEXING: "on"
      REDLIB_DEFAULT_THEME: light
      REDLIB_DEFAULT_LAYOUT: card
      REDLIB_DEFAULT_SHOW_NSFW: "off"
      REDLIB_DEFAULT_BLUR_NSFW: "on"
      REDLIB_DEFAULT_USE_HLS: "on"
      REDLIB_DEFAULT_HIDE_HLS_NOTIFICATION: "on"
      REDLIB_DEFAULT_DISABLE_VISIT_REDDIT_CONFIRMATION: "on"
    healthcheck:
      test: ["CMD", "wget", "--spider", "-q", "--tries=1", "http://localhost:8080/settings"]
      interval: 5m
      timeout: 3s
    networks: [proxy]
    labels:
      com.centurylinklabs.watchtower.enable: "true"
    deploy:
      resources:
        limits:
          memory: 256M
          cpus: "0.5"

networks:
  proxy:
    external: true

Parametry konfiguracyjne

Zmienne REDLIB_<NAZWA> to ustawienia instancji, których użytkownik nie zmieni. Zmienne REDLIB_DEFAULT_<NAZWA> to domyślne preferencje: obowiązują, dopóki użytkownik nie zapisze własnych w ciasteczku. Aktualne wartości pokazuje strona /info instancji.

Najważniejsze opcje Redlib w opisywanej instalacji. Pełna lista w README projektu.
ParametrWartośćOpis
REDLIB_ROBOTS_DISABLE_INDEXINGonrobots.txt zwraca Disallow: /. Chroni przed indeksowaniem, gdyby instancja trafiła do internetu.
REDLIB_SFW_ONLYnieustawione (off)Tryb tylko SFW dla całej instancji, bez możliwości włączenia NSFW w ustawieniach.
REDLIB_ENABLE_RSSnieustawione (off)Kanały RSS subredditów i użytkowników. Wyłączone, adresy .rss zwracają 404. REDLIB_FULL_URL służy tylko do bezwzględnych linków w kanale.
REDLIB_DEFAULT_THEMElightJasny motyw zamiast domyślnego system. Inne to m.in. dark, black, nord, dracula.
REDLIB_DEFAULT_LAYOUTcardUkład listy postów: card, clean albo compact.
REDLIB_DEFAULT_SHOW_NSFW / BLUR_NSFWoff / onPosty NSFW ukryte, a po włączeniu podglądy rozmyte do kliknięcia.
REDLIB_DEFAULT_USE_HLSonFilmy przez HLS (hls.js), z dźwiękiem. Bez tego strona działa bez JS, ale filmy są nieme.
REDLIB_DEFAULT_HIDE_HLS_NOTIFICATIONonUkrywa komunikat zachęcający do włączenia HLS.
REDLIB_DEFAULT_DISABLE_VISIT_REDDIT_CONFIRMATIONonLink „reddit” w nawigacji prowadzi od razu na reddit.com, bez strony z ostrzeżeniem.

Redlib vs Reddit

Zalety

  • Brak reklam i promowanych postów wplecionych w feed.
  • Prywatność: Reddit nie dostaje adresu IP przeglądarki, ciasteczek ani historii przeglądania. Nie ma ekranów „otwórz w aplikacji” ani wymuszania logowania.
  • Lekkość: strona działa bez JavaScriptu.
  • Proste utrzymanie: jeden kontener, bez bazy, sekretów i danych do backupu.
  • Restrykcyjny CSP: strona nie ładuje niczego spoza instancji.

Wady

  • Kruchość: Redlib działa dzięki podszywaniu się pod aplikację Androida i Reddit może to w każdej chwili zablokować, także częściowo (przykład niżej).
  • Jedno wyjściowe IP: przy intensywnym użyciu Reddit może ograniczyć adres domowego łącza.
  • Tylko odczyt: bez logowania, głosowania, komentowania i wiadomości.
  • Brak synchronizacji: subskrypcje są w ciasteczkach, osobno w każdej przeglądarce, bez importu z konta Reddita.
$ docker logs --since 10m redlib
 ERROR redlib::client > Got an invalid response from reddit expected value at line 1 column 1. Status code: 403 Forbidden
 ERROR redlib::utils  > Error page rendered: Failed to parse page JSON data: expected value at line 1 column 1

Rozszerzenie LibRedirect (GitHub, Firefox, Chrome/Chromium) przepisuje linki reddit.com na adres własnej instancji Redlib, tak samo jak linki YouTube na Invidious. W ustawieniach rozszerzenia wystarczy wybrać frontend Redlib i dodać adres instancji jako własną.

Linki