RSSリーダーというものがある。多分同年代にはほとんど伝わらなくて、まあ簡単に言うと、Youtubeのチャンネル登録 + 登録チャンネルの動画を新しい順に並べるというのをWebページでやってくれる。自分が読みたいと思うWebページのRSSを購読 (Subscribe) して、そのページの最新の投稿はRSSリーダーを使って見つける&読むという感じになる。

お察しの通り、2023年においてRSSリーダーなんてものはいらない。企業の最新情報はその企業の広報ブログやPRTimesではなくて公式Xアカウントのポストで知ることになるし、今世間で話題となっていることは中身の伴っていないコメントと一緒にTLに流れてくる。それでも自分がRSSリーダーを使う理由は今のXだったり、自身のおすすめTLをKawaii Pictureで埋め尽くしておきたいという欲求がある。ニュースと一緒に流れてくるキモ=オタクの芯を食わないコメントは別にKawaiiくない。その分RSSリーダーは「ニュースが投稿された」ということだけを教えてくれる。それだけでRSSリーダーの価値はわかってくれるはずだ。

さて、RSSリーダーといえば昔はフリーソフトをインストールする形で使うのが一般的だった。しかし時は令和。Webアプリケーションが幅を利かせるこの時代ではRSSリーダーですらWebアプリケーションである。有名所でいえばFeedlyなどがそれに当たる。自分も今まではFeedlyをずっと使ってきたし、悪いサービスではなかったと思う。ただ、無料アカウントだと登録できるRSS Feedが最大100件であったり、スマホでFeedlyを開いたときのUIが破綻していたりと微妙に不満点はあった。

話は変わるが、「自分はどうやってMisskeyのおひとりさまインスタンスを建てたのか」で建てたMisskeyサーバーがある。このサーバーはXServer VPS上で動いていて、アップデートをしたりMisskeyサービスのメモリアロケータをjemallocに差し替えたりと色々改造工事をしながら今も動いている。特にこのjemallocを導入したのが大きくて、もともと2GBのRAMのうち1.7GB程度を使っていたMisskeyサーバーがわずか1GB程度のメモリのみで動作するようになった。というか、はっきり言うと計算資源を持て余すようになった。

Feedlyへの小さな不満、計算資源の持て余し、ここから導かれる結論は一つ。そう。RSSリーダーサービスのセルフホストである。

RSSリーダー選び

セルフホストできるRSSリーダーというのは意外と多くない。そもそもなぜ既存のアプリケーションをクライアント端末にインストールする方法ではなくWebアプリケーションに拘っているかと言うと、アカウントのログインだけで設定情報などが全て引き継がれるというのが楽だからである。特にデスクトップとスマートフォンの設定を同期できるというのはそこそこありがたい。デスクトップでは簡単なコピペ作業はスマートフォンで辛いというのは知ってのとおりである。

最初はTiny Tiny RSSというRSSリーダーをデプロイしようとしていた。デザインのミニマル感はそこそこ好みだったし、日本語で書かれた構築情報もネットにあったし、公式の構築手順もそこそこ丁寧だった。しかし、デスクトップとスマートフォンの両方でDemoモードに入ってみて理解した。このRSSリーダーはスマートフォン向けに作られていない。というのも、スマホの縦長画面に無理やりコンピューター用の横長UIをはめ込んでいて、視認性が悪かったし、UI同士が重なっていて操作性も悪かった。

ということで、スマートフォン用のUIにも対応したものを探している中でCommaFeedを見つけた。これはスマートフォンのような縦長画面にも対応しているし、デザインもそこそこ自分好みだったので、CommaFeedをデプロイすることにした。

しかし、CommaFeedはインストール手順の解説が結構雑で、そこそこわかっている人がデプロイするアプリケーションという感じがした。自分も結構困った。

Nginxの設定

既にMisskeyサーバーとして公開されているサーバー(VPS)上にデプロイする。そのため、一台のサーバーから複数のサイトを出し分けする必要がある。NginxとかDNSとかをいい感じにすることでいい感じになることは知っていたがその知見がなく、Misskeyでちょっとボヤいたりしていた。

一つのサーバーから異なるサービスを異なるURLで提供する知見が無い
https://post.yourein.net/notes/9lkmlwuw80

そうしたらTLに「バーチャルホスト」という言葉を放流してくれた人がいた。なんか雰囲気的に空リプっぽかったので調べてみたら正解で、実際にはどういう感じになっているかというのが掴めたので良かった。もともとはDNSだったりポートだったりNginxだったりをいい感じにしないといけないと思っていたが、実際にいい感じにするのはNginxだけでいいらしい。

とはいえNginxの設定ファイルを書く技術は持ち合わせていないので、Misskeyサーバーを建てた時につかったNginxの設定ファイルをとりあえず全部コピーしてきて、必要そうなところを書き換えたり消したりすることで解決した。ある程度プログラムをいじっているとプログラムジェンガが上手くなる。最終的には以下のようになった

当然だが、YoureinのRSS.net/hoge/fuga/*は実際のファイルには書いていないので適宜読み替えてほしい。

# Copied from misskey.conf
proxy_cache_path /tmp/nginx_cache/comma levels=1:2 keys_zone=cache2:1m max_size=1g inactive=720m use_temp_path=off;

server {
    listen 80;
    listen [::]:80;
    server_name YoureinのRSS.net;

    # For SSL domain validation
    root /var/www/html;
    location /.well-known/acme-challenge/ { allow all; }
    location /.well-known/pki-validation/ { allow all; }
    location / { return 301 https://$server_name$request_uri; }
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name YoureinのRSS.net;

    ssl_session_timeout 1d;
    ssl_session_cache shared:ssl_session_cache:10m;
    ssl_session_tickets off;

    # To use Let's Encrypt certificate
    ssl_certificate     /hoge/fuga/fullchain.pem;
    ssl_certificate_key /hoge/fuga/privkey.pem;

    # SSL protocol settings
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;
    ssl_stapling on;
    ssl_stapling_verify on;

    # Change to your upload limit
    client_max_body_size 80m;

    # Proxy to Commafeed
    location / {
        proxy_pass http://127.0.0.1:8082;
        proxy_set_header Host $host;
        proxy_http_version 1.1;
        proxy_redirect off;

        # Cache settings
        proxy_cache cache2;
        proxy_cache_lock on;
        proxy_cache_use_stale updating;
        proxy_force_ranges on;
        add_header X-Cache $upstream_cache_status;
    }
}

多分いらない設定項目とかも残っているんだろうが(というかclient_max_body_sizeとかは普通にいらないと思う)、ジェンガを楽しみたいわけではないので、これくらいにしておく。

また、これと同時にYoureinのRSS.netをDNSに登録しておく。

Dockerの設定

おいおいメモリ2GB (Misskeyも動いているので実効1GB程度) のサーバーでDockerを使うのかと思われるかもしれないが、実はTiny Tiny RSSはDockerを用いてのホスティングしかサポートしていなくて、なんかもうDockerをつかって適当にデプロイする気分だったのでDockerになった。

version: "3"
services:
  commafeed:
    image: athou/commafeed:latest
    restart: unless-stopped
    environment:
      - CF_DATABASE_DRIVERCLASS=org.postgresql.Driver
      - CF_DATABASE_URL=jdbc:postgresql://postgresql:5432/commafeed
      - CF_DATABASE_USER=comma
      - CF_DATABASE_PASSWORD=comma
      - CF_APP_STRICTPASSWORDPOLICY=false
      - CF_APP_ALLOWREGISTRATIONS=false
    volumes:
      - /path/to/commafeed/data:/commafeed/data
    ports:
      - 8082:8082

  postgresql:
    image: postgres:latest
    restart: unless-stopped
    environment:
      POSTGRES_USER: comma
      POSTGRES_PASSWORD: comma
      POSTGRES_DB: commafeed
    volumes:
      - /path/to/commafeed/db:/var/lib/postgresql/data

なんかこんな感じでdocker-compose.ymlを書く。
というか、commafeedのdockerhubにある設定例をコピペするだけで動く。自分は多少環境変数をオーバーライドして動かしている。

service化

VPSを再起動しても動いていてほしいので、service化しておく。以下の記事を参考にした。

docker-composeでdockerコンテナをOS起動時に立ち上げる | たくのこ Web

おわり

DNSに登録したページにアクセスしてみると確かにCommaFeedが建っている…

自分でもびっくりするほどあっけなくサービスが建ってしまった。インターネットには様々なサービスをセルフホストで自分用に生やしている人々がいるが、確かにこれくらい気軽にサービスを生やせるならば生やしたくなる気持ちもわかる。それにDockerだったらローカル環境のこととか考える必要ないしな。

VPSのメモリは1GB張り付きから1.45GB張り付きになった。もう一個くらいならなにか軽いサービスを動かせるんじゃないかとか画策してみたり、もうちょっとスペックの良いVPSにプランを変更して最強のセルフホストサービス群を作ってみても良いんじゃないかと思うが、とりあえずしばらくはこのまま運用してみようと思う。また生やしたいものが出てきたら突発的に生やすかもしれない。