部署教程
FreshRSS 部署教程:私人 RSS 阅读器、自动刷新与 OPML 导入
使用 VPS 部署 FreshRSS,介绍配置、访问方式、实际操作及数据备份。
开始前
几个博客、开源项目的更新页,加上自己搭建的 RSSHub,订阅多了以后,最容易乱的是阅读状态:电脑上看过的内容,手机上又出现一遍;收藏的教程散在不同应用里,换阅读器时还得重新整理。
FreshRSS 可以把订阅、文章和阅读状态放在自己的服务器上。浏览器直接读,也可以让兼容的客户端连接它。RSSHub 负责把网站内容变成订阅源,FreshRSS 则抓取这些源,保存文章并提供阅读界面,两者可以配合使用。
本文用官方 Docker 镜像部署 FreshRSS 1.30.0,采用 SQLite 保存数据。先通过 SSH 转发完成安装和订阅,再安排自动刷新,最后处理 OPML 迁移与内网订阅。适合自用,或给少数可信用户使用;不需要为了几个订阅额外维护一套数据库服务。
部署前先确认 VPS 的磁盘、内存和公网访问条件,也可以查看雨云云服务器;注册时填写优惠码 `KuZhuJi`。
注册推荐码:KuZhuJi
先把需要保存的东西分清楚
订阅列表、阅读记录和文章内容不是同一种数据。OPML 文件适合搬走订阅地址及其分组,但不能把它当成完整数据库备份。你把列表导入另一套阅读器,新的服务通常要重新抓取源里目前仍提供的文章;源已经删掉的旧内容,不会因为订阅地址相同就重新出现。
FreshRSS 的数据目录还保存用户配置,以及本文采用的 SQLite 数据库。收藏、已读状态与已抓取文章要跟着数据备份走。后来如果改用 MySQL、MariaDB 或 PostgreSQL,外部数据库也需要单独备份,不能只复制容器里的文件目录。
服务器区域则影响抓取订阅源的网络情况。主要订阅中文博客,可以先看现有 VPS 的出站网络;主要关注海外项目,需要确认它能访问对应网站。阅读器自己能加载首页,并不能证明每个上游订阅源都能正常抓取。
还没有合适的机器,可以在雨云查看云服务器配置与区域,注册时填写优惠码 `KuZhuJi`。优先确认目标源可达、磁盘能保存预期文章与备份,再比较计费周期。套餐库存、优惠资格和最终金额以订单页面为准,不必为了私人阅读器专门追求高频处理器。
用官方镜像,给数据留一个固定位置
准备一台能通过 SSH 登录的 Linux VPS,已有 Docker Engine 与 Compose 插件。下面使用 `docker compose`,不是旧版的 `docker-compose`。命令在自己的用户目录下执行;若当前账号没有 Docker 权限,按服务器实际配置使用 `sudo`。
创建目录:
mkdir -p ~/freshrss
cd ~/freshrss保存 `compose.yaml`:
services:
freshrss:
image: freshrss/freshrss:1.30.0
restart: unless-stopped
ports:
- "127.0.0.1:8089:80"
environment:
TZ: Asia/Shanghai
CRON_MIN: "7,37"
volumes:
- freshrss_data:/var/www/FreshRSS/data
- freshrss_extensions:/var/www/FreshRSS/extensions
logging:
options:
max-size: "10m"
max-file: "3"
volumes:
freshrss_data:
freshrss_extensions:官方镜像的容器端口是80,宿主机使用8089,并且只绑定 `127.0.0.1`。这样初次安装不用将阅读器端口直接开放给互联网。8089已被占用时,修改左侧宿主机端口;容器端口和数据路径保持不变。
两个命名卷分别保存数据和第三方扩展。普通的容器重建不会删除卷,但不要执行 `docker compose down -v`,其中的 `-v` 会要求删除相关命名卷。还要保留这一份 Compose 文件和部署目录:换到另一个目录运行,Compose 项目名称可能改变,随后创建的是另一套卷,页面看起来就像刚安装的新系统。
配置按 FreshRSS 1.30.0 的 Docker 文档编写。该版发布于2026年9月9日,是一次包含安全修复的发布。官方还推荐 `edge` 滚动渠道,以更及时地取得安全补丁;本文固定1.30.0,方便明确配置基线,之后仍应关注更新。固定版本不意味着可以长期不升级,`edge` 也意味着下一次拉取的内容会变化。
执行:
docker compose config
docker compose up -d
docker compose ps
docker compose logs --tail=80 freshrss`docker compose config` 用来确认 Compose 文件格式和展开后的内容。它不代表 FreshRSS 已完成网页安装。日志如果显示端口占用、卷权限或服务启动错误,先解决对应问题,再进入浏览器。
通过 SSH 完成安装,选 SQLite 就够了
在自己的电脑上打开终端,建立转发:
ssh -N -L 8089:127.0.0.1:8089 用户名@服务器IP随后访问本机 `http://127.0.0.1:8089`。这个 SSH 终端需要保持打开,关闭转发不会停止服务器上的 FreshRSS。若本机8089被占用,可以把命令改成 `-L 18089:127.0.0.1:8089`,浏览器相应访问18089。
按安装页完成环境检查和数据库选择。本文使用 SQLite,它由官方镜像支持,不需要再填写远程数据库主机和密码。建立自己的管理员账号,使用独立密码,登录方式选择表单认证。不要把“无需认证”当成方便初始化的默认选项,再忘记改回去。
安装完成后,进入阅读界面,再检查系统设置里的匿名访问与用户注册选项。私人阅读器不需要让未登录的访客读到订阅内容,也不需要向陌生人开放注册。即使订阅的是公开博客,订阅列表、标签与收藏也可能透露你的工作项目和兴趣,不必跟着网页入口一起公开。
如果之后希望通过域名访问,可以把已有的 HTTPS 反向代理接到宿主机 `127.0.0.1:8089`,沿用当前服务器的入口。使用1Panel或已有Caddy时,先检查80、443的归属,避免另启动一套程序抢端口。域名、HTTPS、代理可信来源和应用访问地址应按现有部署方式配置;确认登录、文章链接和订阅管理都能正常使用后,再停用临时 SSH 转发。
只用浏览器阅读时,不需要额外开启客户端 API。以后确实要接手机阅读器,再根据该客户端支持的接口设置相应的 API 访问和凭据。不要把网页登录密码、客户端 API 密码与在线刷新令牌混作同一用途。
准备独立实例时,可在雨云选择适合的云服务器配置,优惠码 `KuZhuJi`。配置按实际任务选择,数据库和附件另做备份。
第一批订阅少放一些,先确认能抓取
从两三个能确定地址的 RSS 或 Atom 源开始。可以订阅一个博客、一个开源项目发布页,再加自己的 RSSHub 路由。很多网站会在页面中声明订阅地址,FreshRSS 可以尝试自动发现;没有找到时,直接填写真正的订阅文件地址。
打开订阅管理,点击添加订阅,将地址粘贴到订阅 URL 一栏。给它分配一个能长期使用的分类,例如“项目更新”“技术博客”或“稍后研究”。不必一开始就分出十几层分类,后面仍然可以移动订阅。
添加后,观察文章标题、时间、链接和正文。一个源只提供摘要,是上游的内容形式,不代表 FreshRSS 出了故障。需要阅读全文时可以点回原网页;FreshRSS 也支持按站点配置正文提取规则,但规则依赖网页结构,不是所有网站都能提取成功。收费内容、登录权限和站点访问限制,不会因为换了阅读器就消失。
先不要一次导入几百个源。错误地址、已停更的源和容易超时的网站混在一起,会让人很难判断安装是否正常。先确认这几个源可以刷新,再逐步导入旧列表。
自动刷新有两个时间设置
Compose 中的 `CRON_MIN: "7,37"` 表示每小时的第7分钟与第37分钟启动内置刷新任务。它不是“每7分钟刷新一次”,也不表示订阅源有新文章就立即抓到。没有设置 `CRON_MIN` 时,官方镜像的内置定时刷新默认不启用。
FreshRSS 还会按订阅源自己的刷新间隔决定是否请求该源。所以,定时任务运行与每个源真正取得新文章,是两件事。源配置为较长间隔时,多运行几次定时任务也不必然让它每次都发出请求。
官方刷新说明指出,全局最低默认间隔不能设得快于20分钟,单个源可以调整到15分钟。需要更及时的更新时,先看上游是否支持 WebSub;不要用每分钟重复抓取代替上游推送,也不要因为看到旧教程中的短间隔命令就直接照搬。
当文章长时间不更新,先手动刷新一个确定正常的源。如果手动成功、自动不成功,检查 `CRON_MIN` 是否确实进入容器环境,以及日志里有没有定时任务执行信息。如果两种方式都失败,则继续检查源地址、HTTP响应、DNS、TLS和出站网络。
修改 Compose 环境变量后,运行:
docker compose up -d --force-recreate freshrss
docker compose logs --tail=80 freshrss不要只执行 `docker compose restart`。重启现有容器不会重新注入修改后的环境变量。前面的数据仍在命名卷中,正常重建服务不会让订阅重新变成空列表。
网页中还有在线刷新入口,可以配合令牌使用。但本例已经使用容器内置任务,不必再给外部定时服务保存一个带令牌的刷新 URL。启用多套定时器之前,先确认有没有重复触发的必要。
需要增加服务器时,可以打开雨云选购页面,填写优惠码 `KuZhuJi`;迁移前保留数据与原有部署配置。
RSSHub 在内网时,1.30 的限制要单独处理
FreshRSS 1.30默认禁止访问本地和内部网络地址。这是本版明确记录的变化,用来降低服务端请求伪造的风险。旧部署升级后,如果原本订阅的是内网服务,可能出现公开源正常、内网源抓取失败的情况。
先区分请求路径。使用公开的 RSSHub 域名时,检查它的公开解析与访问规则;使用 Docker 服务名时,两套容器需要能在相应网络中找到对方。FreshRSS 容器里的 `127.0.0.1` 是 FreshRSS 自己,不是宿主机,也不是 RSSHub 容器。
确实需要访问内网源时,可以在系统配置中增加内部主机允许列表,或使用官方提供的 `INTERNAL_HOST_ALLOWLIST` 环境变量。变量里的条目以空格分隔;使用界面填写时,条目以换行分隔。允许项应针对实际服务与端口,不要为了让一个源恢复,就填入允许全部地址的规则。
例如,某个可信订阅服务在共享 Docker 网络中的名字是 `rss-bridge`、端口为80,可以在 Compose 的环境变量中增加:
INTERNAL_HOST_ALLOWLIST: "rss-bridge:80"这是官方文档使用的主机与端口格式示例,不要求你改装 RSS-Bridge。使用 RSSHub 时,填写实际的服务名与容器监听端口;允许列表本身不会建立 Docker 网络连接,也不会修正错误的服务名。
设置后重新创建 FreshRSS 容器,再手动刷新相关源。只添加需要的目标,不使用 `*` 关闭整个检查,也不为所有 IPv4或IPv6地址统一放行。多人实例需要特别注意,用户提交的订阅 URL 会由服务器发出请求。相关机制见访问控制与内部主机限制。
导入 OPML 之前,保留原阅读器
在旧阅读器中导出 OPML,再到 FreshRSS 的订阅管理中打开导入与导出,选择文件并导入。普通的逐行 URL 文本不是 OPML,不能只把扩展名改成 `.opml` 就当成订阅文件。
导入完成后,核对分类、订阅数量和几个重要源的地址。源里的项目数量由上游决定,很多博客只保留最近若干篇;旧阅读器里已经积累的历史文章,不会单凭一个 OPML 文件全部转移。已读、收藏和自定义标签是否迁移,也取决于使用的导出格式与迁移工具。
FreshRSS 的导出选项还可以包含标记或收藏的文章,它们与“只导出订阅列表”不是同一个范围。迁移前把格式与内容看清楚,再选择导入方式。先确认新阅读器能满足实际需要,旧实例和原始导出文件保留一段时间,避免发现漏掉历史内容时已经没有可回查的数据。
更新前保存完整数据,别只留下订阅地址
使用命名卷部署时,先查询卷名。Compose通常会加上项目名前缀,卷名未必就是 `freshrss_data`:
docker volume ls
docker compose config备份可以使用支持 Docker 卷的现有工具,或者在停掉 FreshRSS 后保存两个卷的内容。采用本文的 SQLite 配置时,停机后再复制数据有助于避免文件仍在变化;如果使用外部数据库,则另行做数据库导出。备份还要保存 Compose 文件和自己添加的配置,存在同一台 VPS 上的备份不能应对整台机器丢失。
更新时,先查看版本变更和升级要求,再修改镜像标签。官方更新文档建议按版本逐步升级,并在每一步确认可用。很旧的实例不要跳过中间版本,直接把标签改成最新;本文是从1.30.0新装,不代替旧版本的升级路径。
新版启动后,确认可以登录、订阅数量合理、收藏能打开,再手动和自动刷新一个源。需要回退时,也不能只换回旧镜像而忽略数据可能已经被新版迁移,旧镜像与更新前的数据备份应配套保留。磁盘空间有限时,先整理文章保留规则与旧备份,别删除正在使用的卷来腾空间。
阅读几天后再调整分类和刷新间隔:更新很少的博客可以拉长间隔,关注中的项目单独分组。删除订阅或改变文章保留规则之前,先导出列表,并确认需要保留的收藏仍在备份中。
