2019 年的今天,白菜价的服务器应有尽有。别的小朋友们服务器上面跑着各式各样的东西:博客、云盘、监控脚本……再看看我们那台闲置很久的阿里云,都已经开始「落灰」了。?‍♂️ 不如把那台服务器拿出来,部署一个属于自己的 RSS 服务器。

RSS 服务

相信少数派的朋友们大部分都对 RSS 已经非常了解了,对于第一次接触 RSS 的同学,推荐大家阅读少数派之前的文章。
市面上有非常多的 RSS 聚合服务,来帮助我们统一管理、订阅、更新、筛选 RSS 源推送给我们的更新信息,避免我们被海量的文章淹没,也能保证我们多个设备上 RSS 的阅读进度一致。Feedly、Inoreader 等等都是非常不错的 RSS 服务,但是它们的免费版本都有着一定的限制,有时候无法满足我们的全部功能需求,而动辄一个月数十刀的订阅费用又让人望而却步。不慌,开源的 RSS 服务:Tiny Tiny RSS 可以满足我们 RSS 订阅的全部需求!

Tiny Tiny RSS 的搭建

Tiny Tiny RSS 是一个非常优秀的开源免费 RSS 服务引擎,可以直接部署在我们自己的服务器上面。借助于 Docker 优秀方便的容器技术和 Let's Encrypt 异常简单的 SSL 证书签署机器人 certbot ,我们几分钟之内就可以部署上线属于我们自己的 RSS 服务,运行在我们可控的服务器上,环境稳定,刷新及时,并且完全免费。?(当然,除了服务器需要一定的费用。)

在容器、HTTPS 证书自动签署和虚拟化技术极度发达的今天,我们的整个部署过程非常方便简单,甚至只利用一台 iPad,我们就可以部署成功。接下来,我只利用 iPad 进行讲解演示我们的部署过程。请大家坐和放宽,我们立刻开始。

准备工作

在开始之前,首先我们需要准备一个位于公网的服务器,以及一个可以通过 SSH 连接到服务器上的本地设备。这里我使用我同学的已经备案的阿里云服务器作为运行 Tiny Tiny RSS 的服务器,通过 SSH 登录服务器。

利用 Docker 部署 Tiny Tiny RSS

安装 Docker

Docker 是非常优秀的虚拟化容器,借助于 Docker 我们可以方便的部署 Tiny Tiny RSS,首先我们在服务器上安装 Docker 本体。在服务器上面执行下面命令来安装 Docker:

curl -fsSL https://get.docker.com/ | sh

然后启动 Docker 服务:

sudo systemctl start docker

然后,我们检查一下 Docker 是否启动成功。我们执行命令

sudo systemctl status docker


看到如上的输出,说明我们 Docker 服务启动成功。

安装 docker-compose

接下来我们安装 docker-compose:一个管理和启动多个 Docker 容器的工具。由于 Tiny Tiny RSS 依赖有 PostgreSQL 的数据库服务以及 mercury_fulltext 的全文抓取服务等等,这些服务我们都借助于 Docker 部署,因此利用 docker-compose 就会大大降低我们的部署难度。
我们继续,在服务器上面执行下面的命令来安装 docker-compose

curl -L https://github.com/docker/compose/releases/download/1.25.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose

之后给予安装好的 docker-compose 可执行权限:

chmod +x /usr/local/bin/docker-compose

最后我们运行 docker-compose --version 来检查安装是否成功。如果有如下输出,说明我们的 docker-compose 安装成功:

安装 Tiny Tiny RSS 及其周边服务

准备工作已经全部完成,接下来我们下载由 Awesome-TTRSS 配置的 Tiny Tiny RSS 服务的 docker-compose 配置文件:

# 创建 ttrss 目录并进入
mkdir ttrss && cd ttrss

# 利用 curl 下载 ttrss 的 docker-compose 配置文件至服务器
curl -fLo docker-compose.yml https://github.com/HenryQW/Awesome-TTRSS/raw/master/docker-compose.yml

修改 docker-compose.yml 里面的内容:

  • 在配置文件的第 7 行和第 23 行,将 PostgreSQL 数据库的默认密码进行修改。暴露在公网的数据库使用默认密码非常危险。
  • 在配置文件的第 18 行,将 Tiny Tiny RSS 服务的部署网址修改为我们实际的部署网址。比如我的部署https://ttrss.tenkeyseven.com 注意,如果你的部署 URL 包含端口(默认部署端口为 181
  • 端口),那么这里的 URL 也需要加上端口号,格式为 {网址}:{端口}不过不必担心,如果你这里的 URL 配置不正确,那么访问 TinyTiny RSS 的时候,Tiny Tiny RSS 会提醒你修改这里的值为正确的 URL,按照提醒进行配置即可

之后,我们保存配置文件,启动 Tiny Tiny RSS 服务。在刚刚的 ttrss 目录下执行:

docker-compose up -d

等待脚本执行完成,如果一切没有问题,那么接下来输入 docker ps,我们应该看到类似下面的结果:

上面内容表示我们开启了四个 Docker 容器,分别是:

  • Tiny Tiny RSS 本身,监听端口为 0.0.0.0:181 → 80,同时暴露给外网
  • PostgreSQL 数据库服务
  • Mercury 全文抓取服务
  • OpenCC 简体、繁体中文转换服务
    如果发现问题,修改 docker-compose 的配置文件后,需要执行下面的命令重启 Docker 容器们:
# 关闭 Docker 容器们
docker-compose down

# 删除已停止的 Docker 容器
docker-compose rm

# ……
# 修改 docker-compose 配置文件
# ……

# 再次开启 Docker 服务
docker-compose up -d

安装 Nginx 作为 Docker 容器的反向代理

事实上,到上一步,如果我们访问{服务器 IP}:181,应该可以直接看到 Tiny Tiny RSS 的 Web 前端,但是 Tiny Tiny RSS 并不能直接配置 SSL 证书,也就没法添加 HTTPS 支持。我们利用 Nginx 作为反向代理服务器,即可方便的给 Tiny Tiny RSS 单独绑定一个我们希望的域名,并利用 Let's Encrypt 来部署 HTTPS。
安装 Nginx
首先我们来安装 Nginx,以 CentOS 为例,我们直接执行下面命令即可:

sudo yum install nginx

之后开启 Nginx 服务:

sudo systemctl start nginx

检查 Nginx 是否启动成功:

sudo systemctl status nginx


开启 HTTPS 支持
之后,我们利用 Let's Encrypt 提供的 certbot 直接为 Nginx 配置 SSL 证书 。以 CentOS 为例子,首先,我们执行下面的命令安装 certbot

sudo yum install certbot python2-certbot-nginx

然后运行 certbot 来签署 SSL 证书并自动配置 Nginx 服务:
sudo certbot --nginx
在这里,certbot 会要求我们输入我们希望签署 SSL 证书的域名,我们选择为 Tiny Tiny RSS 分配的域名(比如我的就是 ttrss.tenkeyseven.com)即可。另外,如果 certbot 询问是否需要将访问该网址的全部流量重定向至 HTTPS,那么选择「是」即可。我们等待脚本执行签署任务完毕,然后重启 Nginx 服务:

sudo systemctl restart nginx

此时我们如果直接访问这一域名,应该就可以看到带有 HTTPS 的 Nginx 默认网站:


接下来,我们修改 Nginx 的配置文件,配置 Nginx 反向代理,将外部访问你的域名(对我来说,就是: https://ttrss.tenkeyseven.com)的请求指向我们刚刚部署好的 Tiny Tiny RSS 服务。对服务器来说,也就是 127.0.0.1:181 这一地址。(如果你没有更改 Tiny Tiny RSS 的端口号的话。)

Nginx 的配置文件位于/etc/nginx/nginx.conf,我们打开这一文件:
http 项下,server 项前定义 upstream 服务:

upstream ttrssdev {
  server 127.0.0.1:181;
  keepalive 64;
}


在刚刚 certbot 为我们生成好的相应域名配置的server 项下,注释掉第一行定义 root 的内容,并将 location / 项修改为:

location / {
  proxy_redirect off;
  proxy_pass http://ttrssdev;
  
  proxy_set_header  Host                $http_host;
  proxy_set_header  X-Real-IP           $remote_addr;
  proxy_set_header  X-Forwarded-Ssl     on;
  proxy_set_header  X-Forwarded-For     $proxy_add_x_forwarded_for;
  proxy_set_header  X-Forwarded-Proto   $scheme;
  proxy_set_header  X-Frame-Options     SAMEORIGIN;
  
  client_max_body_size        100m;
  client_body_buffer_size     128k;
  
  proxy_buffer_size           4k;
  proxy_buffers               4 32k;
  proxy_busy_buffers_size     64k;
  proxy_temp_file_write_size  64k;
}


这样,我们再次执行 sudo systemctl restart nginx 重启 Nginx 服务,一切顺利的话,我们就可以通过我们刚刚签署 SSL 证书的域名访问我们部署好的 Tiny Tiny RSS 服务了!鼓掌 ?
Tiny Tiny RSS 的默认管理员账户、密码是 admin 和 password,请在第一时间进行修改。

配置 Tiny Tiny RSS

如果上面步骤没有问题的话,我们在服务器上面所部署的 Tiny Tiny RSS 本身就已经包含了:

  • Mercury 全文提取服务(默认未开启)
  • OpenCC 繁简自动转换服务(默认未开启)
  • Fever 格式输出插件(默认已开启,用来和 Reeder 等客户端进行连接)
  • 包括 Feedly、RSSHub 在内的多款主题
  • 等等……
    我们不需要多余的配置,开箱即可使用上面的主题和插件,根本不需要操心其他服务的部署和安装。我们登录自己的 Tiny Tiny RSS,在右上角「设置→ 插件」中即可启用上述插件,在「设置 → 主题」处就可以更改我们部署的 Tiny Tiny RSS 所用的主题。

初次配置

安装完成后,访问在上述步骤中设置的网址,即可进入 Tiny Tiny RSS 的 Web 界面。系统默认的管理员账号是 admin,密码是 password

登录后,首先点击 右上角的 Actions… > Preferences… 进入设置页面,进行一些基本配置。

  1. Personal data / Authentication 板块:登录后应立即在此设置新密码。
  2. Preference 板块:

    • Default feed update interval:设置刷新订阅源的时间间隔,应根据自己查看 RSS 的频率和服务器的性能合理安排。考虑到 RSS 一般无须即时性,一般最短 30 分钟的间隔足矣。
    • Enable API access:提供第三方 RSS 客户端支持,务必勾选。
    • Language:语言设置,其中包括简体中文,但翻译质量和完成度均不佳,故本文仍以英文界面为准。
    • Purge articles after this number of days:在指定日期后清除缓存的文章。考虑到目前主流主机服务均以小容量 SSD 存储为主,应合理设置此处期间,以避免占用过多空间,如 30 日。
    • Time zone:设置时区,国内一般设为 Asia/Shanghai 即可。
    • Combined feed display:设置阅读界面布局。默认为两栏式,点击文章列表中的标题后,全文将在标题下展开。如习惯 Reeder 一类传统 RSS 客户端的三栏式布局,取消该项勾选。
      完成后,点击页面底部的 Save configuration 保存配置。

导入、添加和管理订阅

如果你之前使用过其他 RSS 服务,那么直接将订阅源导入即可。方法是:在之前的 RSS 服务后台找到导出为 XML/OPML 的选项,然后在 Tiny Tiny RSS 中进入设置的 Feeds 标签页下的 OPML 板块,选择相应文件导入即可。原有的文件夹结构会被保留。

导入后,可在 Feeds 标签页管理订阅源。Tiny Tiny RSS 提供的管理选项非常详尽,并可以通过拖动来实现排序、分类操作。点击某个订阅源,可以打开更详尽的设置选项。其中比较实用的功能包括自定义订阅源名称、更新频率等。

此外,Tiny Tiny RSS 还提供了一些用于辨识订阅源「健康度」的实用功能。如果有某些订阅源无法连接或长期不更新,那么订阅页面中会分别多出 Feed with errors 和 Inactive feeds 的选项,点击即可查看这些订阅源的出错记录或最后更新时间,并直接批量退订。

2.3 文章过滤

如前所述,强大的过滤功能是促使笔者转投 Tiny Tiny RSS 的首要动力,也是高效处理大量 RSS 订阅源的重要工具之一。Tiny Tiny RSS 的过滤功能分为匹配和动作两个环节,即先根据一定的规则筛出特定文章,然后自动对其实行某种处理。前后两个环节都是可以高度自定义的。

在设置页面中,点击 Filters 标签即可进入过滤设置。首先通过 Create filter 按钮新建一个过滤器。弹出的窗口中,Caption 部分用于指定规则的名称,Match 部分用于设置匹配规则,而 Apply actions 部分则指对被匹配的文章应采取何种操作。
点击 Match 部分的 Add 按钮即可添加匹配规则。你可以指定匹配标题、全文还是两者均匹配,每个匹配规则适用于哪些订阅源。匹配规则支持正则表达式,例如,如果想过滤英文科技博客中常见的赞助广告,那么可以在过滤规则中填入 (S|s)opnsor,这样含有「sponsor」或「Sponsor」的结果都会被匹配。同一个过滤器中可以容纳多个匹配规则,多个规则间默认是相「与」的关系,如果想改为「或」的关系,则须勾选窗口下方的 Match any rule。

对于被筛出的文章,可以选择的操作很多,如标为已读、完全忽略、打上星标等等,并且可以同时适用多个操作。一个比较有趣的操作是 Publish article,它会将文章发布到一个 RSS 源中(该 RSS 地址可在 Feeds 选项卡的 Published & shared articles 区域看到)。进而,结合 IFTTT、即刻等支持检测特定 RSS 源更新的服务,就可实现特定主题实时推送、自动发送到稍后读等高级功能。

不过,过滤功能是比较消耗资源的,如果设置过多的过滤条件,可能给你的主机带来较大压力,因此不应滥用该功能。换个角度来说,当你发现自己将精力不成比例地花在过滤功能上、而非静心阅读文章上时,最应该做的应该不是继续调试过滤、而是清理订阅源。

用插件添加主题、全文输出和多客户端支持

安装主题

前面提到,RSS 服务质量的衡量尺度之一即是界面的设计水平。在这方面,Tiny Tiny RSS 只能说是基本合格:其界面虽然功能全面、且总体上可称之为简洁明了,但细看还是给人一种开源软件常有的「未经打磨」之感。好在 Tiny Tiny RSS 的界面完全基于 CSS,可自行定制或导入主题,这就为「美容」提供了可能。

Tiny Tiny RSS 用户社区产生的主题并不多,但也有不乏几个完成度较高的,如仿 Feedly 和仿 Google Reader 的两个主题。下面以前者为例演示如何安装。

首先获取主题文件:

$ wget https://github.com/levito/tt-rss-feedly-theme/archive/master.zip

然后解压缩该主题

$ unzip master.zip

由于我们的 Tiny Tiny RSS 运行在相对隔离的 Docker 环境中,因此不能像平时那样直接用 cp 命令拷贝文件。为此,首先执行:

$ docker ps

终端将返回当前运行的 Docker 容器列表。我们找到 IMAGE 一列为「fischerman/docker-ttrss」的那行记录,记下同行中 CONTAINER ID 列下的内容。

然后,用 docker cp 命令将上述主题文件拷贝到容器中:

$ docker cp tt-rss-feedly-theme-master/feedly.css [[CONTAINER ID]]:/var/www/themes
$ docker cp tt-rss-feedly-theme-master/feedly [[CONTAINER ID]]:/var/www/themes

请注意将上面命令中的 [[CONTAINER ID]] 替换为你在上一步中获得的内容。

这时,我们就可以在 Preference 页面的 Theme 选项中看到 feedly.css 了。本文截图中的界面均为该主题的效果。

配置 RSS 全文输出

很多网站之所以不欢迎 RSS,一个主要的原因就是提供 RSS 会分走主站的流量;因此,一些网站即便保留了 RSS 订阅源,也做得十分「不情不愿」,只「抠门」地给出前两三段的内容,要看全文还得跳转到网站才行。这显然会破坏 RSS 的阅读体验。于是,获取全文的功能就显得十分必要了;很多 RSS 服务或客户端也将其作为 Premium 订阅的卖点之一。不过,通过 Tiny Tiny RSS,我们同样可以免费实现这一效果。

事实上,Tiny Tiny RSS 原本已经内置了基于 Readability 的全文输出服务,但可惜这家服务在前段时间已经跑路,关闭了 API 接口,我们只能另请高明。目前,比较好的替代方案是 Mercury,这也是 Reeder、Unread 等主流 RSS 阅读器在近期更新中改用的方案。

首先,Mercury 的全文输出服务是免费的,但需要配合 API 密钥使用,这可以在注册后在其网站的 Web Parser 页面看到。

接着,为 Tiny Tiny RSS 安装全文输出插件,其方法与安装主题完全相同:

$ git clone https://github.com/WangQiru/mercury_fulltext.git
$ docker cp mercury_fulltext [[CONTAINER ID]]:/var/www/plugins

安装后,到 Tiny Tiny RSS 的设置页面中启用名为 mercury_fulltext 的插件。这时,在设置页面的 Feeds 选项卡下,就会多出一个该插件的设置区域。我们将之前获得的 Mercury API 密钥填入文本框中,并点击 Save 保存配置。

完成上述准备工作后,就可以针对特定的订阅源启用全文输出了。方法是:在订阅源管理中,点击需要获取全文的订阅源,在弹出的 Edit Feed 对话框中,勾选 Plugins 选项卡中的 Get fulltext via Mercury Parser。

该插件的效果如下(The Verge):

让更多客户端支持 Tiny Tiny RSS

在 RSS 的使用体验中,客户端是十分重要的一环;缺少第三方客户端支持的 RSS 服务注定只能是「孤家寡人」。然而,作为一个小众的开源软件,Tiny Tiny RSS 在这方面显然不能与那些商业服务相比。主流的客户端软件中,只有 Fiery Feed 提供了对 Tiny Tiny RSS 的原生支持。

好在开放的插件系统这时再次发挥了作用。借助第三方插件,Tiny Tiny RSS 可以将自己模拟为另一个自建 RSS 工具——Fever,而后者的客户端支持更为全面,包括 Reeder、Unread 等。[3]

第一步仍然是安装插件:

$ git clone https://github.com/rannen/tinytinyrss-fever-plugin.git
$ docker cp fever [[CONTAINER ID]]:/var/www/plugins

安装后,在 Tiny Tiny RSS 的设置页面启用名为 fever 的插件。保存后,再次进入设置时,Preference 选项卡下会多出一个名为 Fever Emulation 的板块。在该板块的文本框中,设置一个专用于该插件的密码,然后点击 Save。该文本框下方同时给出了一个独立的服务器地址,其格式类似于 http://rss.example.org/plugins/fever/。将其记下以备后用。

这时,在 Reeder 等 app 中,只要在添加 RSS 账号时选择 Fever,在服务器地址栏填入上述地址,即可配合这些你惯用的 app 使用 Tiny Tiny RSS 了;文件夹、标为已读、星标等功能均被良好支持。

总结

以上就是使用 Tiny Tiny RSS 自建 RSS 服务的全过程。可以看出,虽然听起来很 geeky,但实际操作比想象的简单很多,稍微熟悉后不到半个小时就可架起服务并使用。从我两个月的使用体验看,它基本已经完全代替了之前对 Feedly 和 Inoreader 的需求,且无论是灵活性还是性价比都是第三方服务无法比拟的。

当然,一旦涉及到这种 DIY 操作,总是要回应的质疑是:这么做值得吗?毕竟,「RSS 已死」不是什么新鲜论调了。这么说的人中,有的是 RSS 曾经的忠实用户,感慨曾经活跃的第三方软件和服务逐渐冷却;有的是新世代新闻、阅读服务的开发者,鄙弃 RSS 的老旧和刻板。

然而,RSS 说到底是一个协议。而协议只在一种情况下可以被宣告死亡:再也没有人使用的时候。诚然,如果只论 RSS 最「原教旨」的形态,其占有率确实几乎可以忽略不计了;但当下那些看起来更「现代」的资讯工具,尽管可以在界面、交互上不断翻新,但其本质仍然是一个时间线上的信息流,其中每篇内容包含的要素仍然是标题、时间、正文等 RSS 已经涵盖的要素。易言之,它们归根结底都是 RSS 的衍生物。从这个角度看,RSS 没有死、也不会死。

必须承认,新技术加持下的现代工具在配置和使用上都远比 RSS 来得便利和舒适。但,在获得便利的同时,你也将选择的权利让渡给了机器,将偏好和隐私让渡给了第三方;在追求舒适的另一面,是被无限信息流淹没的宝贵时间,和被算法推荐不断强化的「回音壁」效应。相反,RSS 是有限的,因此也是克制的;是刻板的,因此也是高效的;是不智能的,因此也是包容的。

在今天,坚持使用 RSS,能让你真正认真思考自己对信息的需求,在喧闹而充满误导和诱惑的信息海洋中守住自己对信息获取的控制权;而自建 RSS 服务,则是维护这种控制权的终极途径。

  • 有的系统可能没有安装 unzip 命令,这时可先运行 apt-get unzip 安装该功能。
  • 要运行 git 命令,你的主机需要先安装 git;如果运行时提示未安装,请使用 apt-get git -all 命令来安装。
  • 遗憾的是,Fever 也在去年圣诞节前夜跑路了,这也是它没有成为本文主角的原因。
  • ttrss+mercury+fever+feverAPI模拟四合一docker
Last modification:November 25, 2019
如果觉得我的文章对你有用,请帮忙点一下上面的广告