之前一直在使用 Inoreader,最近实在是受不了它的速度所以考虑更换 RSS 服务,参考了很多最终选择自己搭建一个 Tiny Tiny RSS (TT-RSS) 服务,本以为十分成熟的配置流程结果处处是坑,所以还是单独记录一下方便查阅。
大部分网上关于 TT-RSS 的配置教程都是基于 Docker,对于我这种不喜欢使用 Docker 的百无一用,而少数自己在服务器上手动配置的也是年代久远,配置过程中的各种错误也没有什么很好的解释。尤其是像 Mercury 这种官方关闭服务的,我也是折腾好久才搭好了一个 API。
本文主要内容包括:
TT-RSS 在个人 Server 上的搭建方法
TT-RSS 后台自动更新 Feeds
Fever API 配置
搭建个人 Mercury-Parser API
还会稍微介绍一下常见的 TT-RSS 设置(如主题、客户端等)
准备工作和安装
服务器配置
Vultr 服务器,公网 IP,有解析域名,希望能够通过子域名访问 Web 端 RSS 服务。
因为不是直接在 Docker 上部署,所以在正式安装前,需要进行一些服务器端的操作,以下操作都能通过 Google 解决,有搭建网站经验的应该很快就能搞定。
子域名解析
LNMP 环境配置(已安装的可以跳过,注意后面会用到 LNMP 的安装包)
Nginx 网站配置(根目录,SSL,重定向等)
申请 SSL 证书
下面是我使用的 nginx.conf
,可以参考添加到自己的配置文件中:
Code
1 | server |
到此当你访问自己设置的域名时应该会出现 nginx 已安装的界面。
安装 TT-RSS
接下来就是正式安装 TT-RSS,这个环节没有太大问题,只是有些小 Bug 需要注意。
首先,我选择的数据库是 MYSQL,官方推荐采用 PostgreSQL,不过两者大同小异。在正式安装前,我们需要手动在 MYSQL 中创建用户 ttrss
和名为 ttrss
的数据库(用户名和数据库名也可以自行设置)
使用 Git 拉取安装包(TT-RSS 是在其作者自建的 Gogs 上),以下涉及 $ROOT_DIR
的更换为自己的网站根目录。
Bash
1 | cd $ROOT_DIR # 进入网站根目录 |
实际安装中会出现以下权限问题,所以我们先设置好文件权限:
Bash
1 | chmod -R 777 $ROOT_DIR |
刷新我们的网站,此时应该能够正常进入安装界面了,我们在表中填入之前创建好的数据库名及数据库用户名,Tiny Tiny RSS URL
处填写我们的域名,点击 test configuration 就能完成安装了。
在这个环节容易遇到以下错误:PHP function mime_content_type() is missing, try enabling fileinfo module.
原因是 PHP 缺少 fileinfo 模块,这时我们需要用到 LNMP 安装包,重新对 fileinfo 这个模块进行编译安装,具体操作可参考:《手动为已编译的PHP加入fileinfo扩展模块》
TT-RSS 安装步骤并不复杂,如果没有报错一切进行顺利,最后点击按钮 Return to Tiny Tiny RSS
即算正式完成安装。
进入登录界面,初始用户名和密码分别为 admin
和 password
,记得登录成功后第一时间修改密码。(盗用一张 Web 主界面)
TT-RSS 的后台配置十分简洁,说明也很清晰,配合汉化根据自己需求进行选择即可。
TT-RSS 后台自动更新 feeds
官方文档:《UpdatingFeeds - Tiny Tiny RSS》
官方文档写的比较简略,主要介绍了三种办法:1)手动;2)后台自动,使用 crontab
;3)前台自动。本来使用 crontab 是个执行定时更新的好办法,但是网上找到的教程乱七八糟,大多教程配置出来根本就不能正常更新,有的甚至是把后台更新跟前台更新混淆在一起,事实上 crontab 根本没有运作。
crontab 定时更新
TT-RSS 更新脚本文件 update.php
或 update_daemon2.php
不能由 root
用户来执行,比较合适的是通过 nginx 的运行用户 www
来执行。
crontab 命令被用来提交和管理用户的需要周期性执行的任务,与 windows 下的计划任务类似,当安装完成操作系统后,默认会安装此服务工具,并且会自动启动 crond 进程,crond 进程每分钟会定期检查是否有要执行的任务,如果有要执行的任务,则自动执行该任务。
crontab 的基本语法如下:
Bash
1 | # .---------------- minute (0 - 59) |
简单来说,设定好执行时间周期以及需要执行命令就可以了,但是由于 TT-RSS 的更新脚本不能用 root 执行,所以网上教程很多不规范的代码实际并不能运行。下面代码是我参考官方文档,使用 www
用户执行,并且测试成功的:
Bash
1 | # 以下内容均在 root 用户下执行 |
需要注意:
定时时间可以自行修改
为了保证 crontab 正常运行,一定先在
cron.allow
中写入执行用户/usr/local/php/bin/php
要修改为你的 PHP 执行文件的地址,也可能是/usr/bin/php
,以个人系统为准update.php
的绝对路径不能出错
另外,如果你不是在 root 用户下执行以上命令,比如也可以直接在 www 用户下执行:
Bash
1 | vi /etc/cron.allow # 该语句执行仍需要 root 权限 |
crontab 语句不能写成 */30 * * * * www /usr/local/php/bin/php /安装TT-RSS的目录/update.php --feeds --quiet
Each cron command followed by a username, only if it is the system crontab file
crontab 接用户名的语法只能是用在系统调度的 crond 文件中,而我们使用的只是单个用户下的 crond 进程。
在此之后,可以通过以下几个方法查看 crontab 是否配置成功以及是否执行:
为了检验 crontab 的命令是否正常运行,可以将上图中 command 语句复制出来手动执行一次(需要在 www 用户下执行),这时可以把 --quiet
去掉,如果能够正常运行,并且网页上显示 feeds 最新的更新时间,那说明定时任务配置成功。
手动更新时可能会出现警告:Warning: exec() has been disabled for security reasons in /update.php
原因是 exec() 函数因为安全原因被禁止。
我们需要找到 php.ini
,其中 disable_function
选项中为禁用的函数,删掉 exec
,重启 php 服务即可。
前台自动更新
在官方文档中,还介绍了一种更新方法:Simple background updates
,我称之为”前台更新“。也就是只要在浏览器中开着 TT-RSS 的网页,它也可以按照你设置的更新时间定时更新 feeds。
If all else fails and you can’t use any of the above methods, you can enable simple update mode where tt-rss will try to periodically update feeds while it is open in your web browser. Obviously, no updates will happen when tt-rss is not open or your computer is not running.
配置方法为:将 config.php
中的 SIMPLE_UPDATE_MODE
设置为 true
即可。不过这种办法只适合于浏览器打开的场景,其他使用 TT-RSS API 的程序并不支持这种更新方法。
在网页端设置的定时更新时间与 crontab 的更新时间是有关的,如网页端设置 4 小时更新,crontab 设置 30 分钟更新,实际上后台 feeds 更新的频率是 4 小时。这应该是一个优先级的问题,具体程序怎么调整的就没有深究了。
Fever API 配置
GitHub: DigitalDJ/tinytinyrss-fever-plugin: Tiny Tiny RSS Fever API Plugin
Fever API 主要是为 TT-RSS 提供一个多端同步的功能,配置方法相对简单:
Bash
1 | cd $ROOT_DIR/plugins.local |
在 TT-RSS 后台开启 允许外部客户端通过 API 来访问账户
以及在插件中勾选 Fever
并保存,此时就能看到 Fever Emulation
设置界面。
设置 Fever API 的独立密码,可以看到图中的 Warning,建议设置独立密码。设置好后,在支持 Fever API 的客户端上,使用 API URL 和用户名密码登录即可,注意 API URL 要使用上图红框中由插件给出的地址。下图为 Reeder4 的登录界面:
好在 Fever API 还在缓慢更新,所以为了解决一些 Bug,以后可以手动更新插件:
Bash
1 | cd $ROOT_DIR/plugins.local |
相关问题:Fever API 无法保存密码
Fever 插件配置界面点击保存没有任何反应,而且下次打开配置界面,显示的密码还是为空。那么密码到底是否设置成功呢,答案是”成功了“。
在插件配置界面 F12
,切换到 Network
选项,然后输入密码点击设置,当我们看到名为 backend.php
出现并且状态码为 200
时说明密码设置是成功的。
如果还不放心,进入数据库后台 phpadmin
,找到 ttrss 数据库下的表单 ttrss_plugin_storage
,可以看到下面 Fever 那一行的数据相比未设置时是发生了改变的,并且你可以重复操作几次,确定表单中密码相关的内容具有一致性。(当然,最好的方法还是直接用客户端试一试)
这个问题在 Docker 版的多合一安装包中貌似也存在,所以只能等待未来插件的作者修复这个 Bug 了。
TT-RSS 全文输出
RSS 可以方便人们更高效的获取信息,但是对于网站来说其实是损失了部分网络流量,一些论坛或者门户网站会将 RSS 链接隐藏起来或者是只输出部分文章内容,所以在阅读 RSS 时你需要再跳转到原始网址才能完整阅读。
当然,对于我而言,全文输出的功能只是”锦上添花“,并非”必不可少“。我主要是用 RSS 订阅论坛更新和一些博主,有感兴趣的内容我会更倾向于去原网站阅读,因为原网站自身的排版和样式无疑还是比 RSS 单一的图片和文字输出要生动许多。
在配置这个功能之初稍稍做了一下工作,目前 TT-RSS 常用有两个方法来实现全文输出:
采用自带的
af_readability
插件使用
Mercury Parser API
可能因为早期的 af_readability 效果不好,大多数教程上来就直接配置 Mercury,结果我也花了大量时间在填这个坑。而事实上 af_readability 是 TT-RSS 作者在维护,不说实用性,至少兼容性是完全没问题的,而且在持续更新,就个人测试而言目前的 af_readability 更加实用。
搭建 Mercury-Parser API
可以认为 Mercury 就是一个爬虫 API,你将需要爬取的网址发送给 Mercury 服务器,然后它返回全文的内容。遗憾的是 2019 年 Mercury 就开源代码然后彻底关停官方服务了。因此网上几乎所有 Mercury 相关的教程都失效了。
February 2019, Postlight announced they were discontinuing the hosted service and open-sourcing the code.
Postlight 也给出了一个自建 API 的方法:《postlight/mercury-parser-api》。不过这个方法并不太适用自己在服务器上搭建,反而像是为 Docker 和 AWS 量身定做。另外,官方的搭建方法输出端口为 3000,不知道去哪里修改,这直接跟我服务器在跑的有些服务冲突,于是干脆放弃。想着用 Mercury Parser 的源代码搭一个类似的 Web API,Google 了好久还真让我发现了一篇自建 Mercury Parser 的文章:
Replacing Postlight’s Mercury scraping service with your self-hosted copy – Babak Fakhamzadeh
Mercury Parser 本身就是依靠 node 搭建的,那就方便了,用 expressjs 包装一下,一个 web API 就诞生了。
首先,我们需要创建一个文件夹来安装 mercury parser,需要保证的是这个文件夹能简单的通过域名访问到,如我在 TT-RSS 目录下新建文件夹 mercury
,然后可以通过 rss.phower.me/mercury
来访问。接下来就是 API 的搭建。
Bash
1 | cd $ROOT_DIR/mercury |
在 /mercury/
中创建 app.js
文件,填入以下内容:
Javascript
1 | const express = require('express'); |
执行此文件:
Bash
1 | node app.js |
此时访问 rss.phower.me:1234/mercury/?url=https://www.baidu.com
可以看到 parser 抓取的全文内容,说明服务搭建成功。
接下来我们需要该 web API 能在后台运行:
Bash
1 | npm install forever -g |
此时 Mercury Parser API 就算是完整搭建起来了,以后只需要通过访问 rss.phower.me:1234/mercury/?url=网址
就可以获得全文抓取的内容。值得提醒,因为这个 API 没有提供任何用户认证和防爆措施,所以部署的端口号以及文件夹名按照个人喜好来设置,以防滥用。当然也可以配置一下 nginx 的反代来隐藏端口号等信息,这就是后话了。
TT-RSS Mercury 插件
上一节其实都算是为使用 mercury 插件的准备工作,这里才是正式的插件配置方法。目前 TT-RSS 中使用的 mercury 插件是 mercury_fulltext,其作者也是 TT-RSS Docker 版的开发者。
由于原插件适配的是 Docker 版本和早期 postlight 的 API,所以我进行了一些小改动,可以支持自己配置的 mercury API。
使用 git 获取插件:
Bash
1 | cd $ROOT_DIR/plugins |
进入后台先在插件列表启动 mercury_fulltext
,此时在信息源页面出现相关的设置界面,填入上一节中配置好的 mercury API URL,如 rss.phower.me:1234/mercury/
,注意不要包括后面的网址等链接。
对需要全文输出的信息源,我们还需要手动启动 mercury 全文输出支持,等待下一次该信息源有更新时就能够看到全文输出的内容了。如果需要调试,也可以使用 调试信息源
功能,勾选 force refresh
和 force rehash
,看到 mercury_fulltext 有对应的运行时间时说明 API 已经正常工作,返回主界面可以看到原有节选内容已经变成了全文输出。
如果是使用的 HenryQW 的插件,请自行修改 init.php
:
Php
1 | // 找到下面这一行代码,第 200 行附近 |
af_readability 插件
相比 mercury 我其实更加推荐 af_readability,即官方的全文输出插件。测试了几个我常用的信息源均能正常抓取,抓取质量跟 mercury 相比几乎没有什么区别。而且 af_readability 还有一个吸引我的地方就是它有一个 toggle
按钮,即使你没有为这个信息源配置全文输出,也可以通过这个按钮进行二次抓取并且实时显示在页面中。
使用方法跟 mercury_fulltext 类似,不需要额外安装,难度系数极低。启动插件后在后台全局设置中勾选为 核心代码和其他插件提供全文服务
,然后对于需要全文输出的信息源勾选 inline 文章内容
。没有勾选该功能的信息源也可以使用 手动切换
全文输出,如果需要在移动端直接查看全文的必须勾选 ”inline 文章内容“。
下面是 ”Chiphell 新闻“ 的全文输出对比,目标网站是论坛形式,可以看出 af_readability 更美观一些,不过总体来说大同小异。mercury 是采用的自建 API,官方也有一些扩展功能的配置方法,而 af_readability 是原生插件稳定性肯定更好。