起因
TTRSS 的 web 页面在小屏移动设备根本不可用。 Reeder 对 TTRSS 的 Fever API 的支持同样烂,好半天同步不下来阅读列表。不过可以理解,毕竟 Reeder 早就把 Fever 标记成 Deprecated,给用户打过预防针了。
寻觅许久,终于找到了一款 iOS 上对 Fever 支持良好的阅读器,名叫 Unread。交互极佳,界面好看,不用付费就能使用大部分功能,十分良心。
关于 RSS 的事情本该在此告一段落了,但是我总感觉 TTRSS 太慢了——前端通常要花费数秒钟才能加载到可用程度。另外 Reeder 也始终让我心痒痒:我花钱买的软件就这么搁置了——不行,太浪费,必须找个理由用起来!
Reeder 另外支持的自建协议是 FreshRSS 和 Google Reader API,根据这两种协议找到了另外两款比较主流的能够自建的 RSS 服务:FreshRss 和 Miniflux。
FreshRSS 也是基于 PHP 开发的,提供 Fever 和 Google Reader API,界面比较简单。FreshRSS 可以使用 SQLite 作为数据库,对内存或者磁盘不足的机器十分友好。
Minuflux V1 由 PHP 开发(2013 - 2018),V2 使用 Golang 开发(2018 - ),提供 Fever 和 Google Reader API。
最终选用 Miniflux 的大体原因是因为:
- Miniflux 的官网和介绍很有趣,能感受到作者对作品的自信、对“精简”这一理念的坚持
- Miniflux V2 使用 Golang,比起 PHP 我更喜欢 Go
- FreshRSS 用了一个叫 MinZ 的、连文档都没有的框架,我不喜欢
此外,Miniflux 还有许多吸引人的特性:
- Golang 开发,性能和部署优势
- 内存占用比较低(我通过 Portainer 观察是 25MB - 50MB 左右,作为对比 TTRSS 大概是 100MB - 180MB)
- 提供 OpenAPI、Fever API、Google Reader API
- 精简、专注核心功能、无插件,JavaScript 使用很克制
- (不需要插件的)全文拉取功能
- 服务端渲染
不算优势吧 - 界面简洁,PWA 支持,小屏移动端体验良好
- 快捷键支持
- 提供许多 Read It Later 服务的接入功能
- 开发理念很棒,代码质量把控严格
部署
docker-compose.yml
:
version: '3.4'
services:
miniflux:
image: miniflux/miniflux:latest
container_name: miniflux_rss_server
restart: always
ports:
- "183:8080"
depends_on:
- db
environment:
- DATABASE_URL=postgres://miniflux:password@db/miniflux?sslmode=disable
- RUN_MIGRATIONS=1
- CREATE_ADMIN=1
- ADMIN_USERNAME=admin
- ADMIN_PASSWORD=password
- BASE_URL=https://rss2.bolitao.xyz
- CLEANUP_ARCHIVE_UNREAD_DAYS=-1
- CLEANUP_ARCHIVE_READ_DAYS=200
- POLLING_FREQUENCY=20
healthcheck:
test: ["CMD", "/usr/bin/miniflux", "-healthcheck", "auto"]
db:
image: postgres:15
container_name: miniflux_db_postgres
environment:
- POSTGRES_USER=miniflux
- POSTGRES_PASSWORD=password
volumes:
- miniflux-db:/var/lib/postgresql/data
healthcheck:
test: ["CMD", "pg_isready", "-U", "miniflux"]
interval: 10s
start_period: 30s
volumes:
miniflux-db:
之后使用 docker-compose up -d
命令运行,打开 <ip>:<port>
即可访问页面:
添加自定义 CSS,把链接中(github/fengkx/miniflux-theme-pure/master/dist/style.css)的内容复制到 Miniflux 设置中“自定义 CSS”输入框即可。后来我觉得默认样式也不错又把自定义 CSS 去掉了。
完成基础部署后,导入从 TTRSS 导出的 OPML 文件,恢复订阅链接。导入之后有一个问题,就是阅读进度都被重置了,我的未读变成了恐怖的 10k+,不过问题不大,历史文章我几乎都已经阅读过了,所以只需要浏览完近几天更新的 RSS,然后直接把所有文章标记成已读就好。
域名
在域名管理界面配置 DNS。
接着配置 Nginx 反向代理:
vim /etc/nginx/sites-enabled/miniflux.conf
配置内容:
server {
server_name rss2.bolitao.xyz;
client_max_body_size 128M;
location / {
proxy_pass http://127.0.0.1:183;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Ssl on;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Frame-Options SAMEORIGIN;
client_max_body_size 128M;
client_body_buffer_size 128k;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
}
}
检查配置:
nginx -t
# output:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Reload nginx:
nginx -s reload
启动 certbot:
certbot
# output:
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Which names would you like to activate HTTPS for?
We recommend selecting either all domains, or all domains in a VirtualHost/server block.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: docker.bolitao.xyz
2: pw.bolitao.xyz
3: rss.bolitao.xyz
4: rss2.bolitao.xyz
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel): 4
然后就可以通过域名访问网站了:
在此之后,可以在 Cloudflare 的 DNS 配置中,把代理打开:
备份方案
Miniflux 本身不在机器产生什么数据,只需要备份数据库就好。所以参考原来的 TTRSS 备份脚本,简单改改就能用了。
vim /root/scripts/miniflux_backup.sh
脚本内容:
#!/bin/bash
SCRIPT_DIR="/root"
NOW=$(date +"%Y%m%d")
TMP_PATH='/tmp'
DOCKER_NAME='miniflux_db_postgres'
MINIFLUX_DB="$TMP_PATH/miniflux_db.sql"
BAK_FILE_NAME="miniflux_db-$NOW.tar.gz"
BAK_FILE="$TMP_PATH/$BAK_FILE_NAME"
DROPBOX_DIR="/root/dropbox"
docker exec "$DOCKER_NAME" pg_dumpall -c -U miniflux > "$MINIFLUX_DB"
echo "数据库 SQL 导出完毕,正在打包压缩..."
tar cfzP "$BAK_FILE" "$MINIFLUX_DB"
echo "打包完成,准备上传..."
"$SCRIPT_DIR"/dropbox_uploader.sh upload "$BAK_FILE" "$DROPBOX_DIR/$BAK_FILE_NAME"
if [ $? -eq 0 ];then
echo "上传完成"
else
echo "上传失败"
fi
rm -f "$MINIFLUX_DB" "$BAK_FILE"
随后赋权,试运行一遍:
chmod +x /root/scripts/miniflux_backup.sh && bash /root/scripts/miniflux_backup.sh
输出:
数据库 SQL 导出完毕,正在打包压缩...
打包完成,准备上传...
> Uploading "/tmp/miniflux_db-20230111.tar.gz" to "/root/dropbox/miniflux_db-20230111.tar.gz"... DONE
上传完成
然后配置定时任务:
crontab -e
打开的编辑器中添加以下行:
0 3 * * 0 /bin/bash /root/scripts/miniflux_backup.sh > /dev/null
完毕。
TTRSS 星标数据处理
把数据迁得差不多之后,为了节省一些 VPS 的资源,我准备关闭原来的 TTRSS 实例、进行一些清理工作。但我发现待办中还有最后一项让我头疼的事,那就是我的 TTRSS 有许多收藏的文章,我得想办法把它们导出。
我首先想到的是把这些东西导出到 Miniflux,但是有点困难,退而求其次准备把他们导出到 wallabag。
插件方式
首先,需要在 TTRSS 部署 ttrss-to-wallabag-v2 插件。我使用的是 Awesome TTRSS 的镜像,默认已经自带 ttrss-to-wallabag-v2 插件,只需要将其开启即可。
编辑 TTRSS 的 docker-compose.yml
文件,修改环境变量,在 ENABLE_PLUGINS
后添加 wallabag_v2
:
添加完成后重启 TTRSS。
之后去到 wallabag 页面,右上角点击头像 - API 客户端管理,创建一个新的客户端:
将该值填入 TTRSS 的设置 - Wallbag V2 设置:
然后就可以在 TTRSS 通过快捷键 a w
,把文章加入 wallabag 了。
但是我有数百篇 Star,一篇篇添加太费劲。我想过用 TTRSS 的 Filter 功能把星标文章导出到 wallabag,但是 Filter 没有针对 Star 文章或 labels 进行操作的功能。于是,这个方案被我废弃掉。
通过 API 自行导出
我看了下 TTRSS Fever API 和 wallabag API 的文档,发现其调用不算困难,于是在 ttrss-to-wallabag-v2 这个插件的提示下,准备自己写一个小玩具进行导出。
开发过程中使用 Unirest 库调用 Wallabag 的 /api/entries.json
API 时一直出现 HTTP 500,Wallabag 的文档和日志太烂,根本没地方查错,差点想放弃。最后干脆摆烂拷贝 Apifox 生成的调用示例代码竟然调通了...原来是 Header 需要多加个 Content-Type: application/json
。
玩具的功能很简单,调用 Fever API,获取 TTRSS 加星标的文章,然后通过 wallabag 的 API 导入,没有日志,没有异常保护,没有多线程。我自己跑 716 篇文章迁移耗时大概十五分钟,检查后没有出现数据丢失。如果真丢了,也定位不到哪篇丢了,因为我没加日志框架。
代码在这里,需要 JDK 8:
bolitao/ttrss-starred-to-wallabag: Tiny-Tiny-RSS starred articles to wallabag
体验
完爆 TTRSS,Miniflux 的全文拉取很好用,页面体验非常舒适,还支持 PWA!
有一个小瑕疵——iOS 字体显示有问题,我在 Miniflux 设置的字体是 Serif,但是 PWA 应用依旧是显示非衬线字体。猜测是 iOS 的通病,因为即使我用 Reeder 阅读器设置衬线字体,也依旧会使用系统默认的非衬线字体显示中文。
最后,诚心推荐 RSSHub 及 RSSHub Radar,RSSHub 可以将许多网站内容转为 RSS 订阅链接,Radar 可以检查网站的可订阅内容、一键订阅内容到 TTRSS / Miniflux。我主要用它订阅一些视频和社交博主的更新以及订阅一些瑟瑟内容。服务可以免费部署在 Vercel 上,记得在环境变量设置一下访问密钥以避免 Vercel 用量超量。
Ref.
- Miniflux Documentation - Installation Instructions
- v2/contrib/docker-compose at main · miniflux/v2
- miniflux, docker-compose, nginx
- 🐋 Awesome TTRSS | 🐋 Awesome TTRSS
- joshp23/ttrss-to-wallabag-v2: A Tiny Tiny RSS plugin to post to a Wallabg v2 instance
- wallabag API documentation
- tinytinyrss-fever-plugin/fever-api.md at master · DigitalDJ/tinytinyrss-fever-plugin
- wallabag API · GitBook