XF

服务部署 Step 2. FreshRSS

部署完Traefik之后,我们来部署 FreshRSS 服务器。

关于什么是 RSS,及 RSS 相关软件、服务和平台,可以参考如下 2 个外部链接:

数据持久化

由于 Docker 的特性,当一个容器被销毁,其中的所有数据也会随之丢失。每当我们部署的服务有更新(有了新的镜像),我们拉取新的镜像并启动新容器的时候,我们就会丢失所有数据。这当然不是我们想要的,我们希望每次更新新的镜像时,用户数据能够得以保留,只有软件程序本身被更新。

因此我们使用 Docker 映射数据卷的功能,来将用户数据持久化。一个容器并不是所有的数据都需要持久化:

创建项目文件夹

注 2本文自建 FreshRSS 容器要成功运行,前提是已经完成前面文章中启动 Traefik 容器的步骤。

沿袭我们之前文章的文件目录结构,我们把 docker-compose.yml 等配置文件放在 ~/site 的子目录中,子目录以服务的名字命名,即 freshrss;把数据卷放在 ~/volumes 的子目录中。

FreshRSS 需要使用一个数据库后端,可选 MySQL/MariaDB, SQLite3 或 PostgreSQL。这里我们选择 PostgreSQL。

mkdir -p ~/site/freshrss
mkdir -p ~/volumes/freshrss/{data,postgres,extensions}

vim ~/site/freshrss/docker-compose.yml

这几个文件夹里面目前什么都不需要放置,一切需要的东西都会在 FreshRSS 初始化时自动生成。

配置文件

这里直接给出 docker-compose.yml 配置文件的内容:

# docker-compose.yml

version: "3.5"

services:
  freshrss_postgresql:
    image: postgres:12
    container_name: freshrss_postgresql
    restart: always
    volumes:
      - freshrss_pgdata:/var/lib/postgresql/data
    environment:
      - POSTGRES_USER=freshrss
      - POSTGRES_PASSWORD=freshrss
      - POSTGRES_DB=freshrss

  freshrss:
    image: freshrss/freshrss
    container_name: freshrss
    restart: always
    depends_on:
      - freshrss_postgresql
    volumes:
      - freshrss_data:/var/www/FreshRSS/data
      - freshrss_extensions:/var/www/FreshRSS/extensions
    environment:
      - CRON_MIN=*/20
      - TZ=Asia/Hong_Kong
    labels:
      - "traefik.enable=true"
      # Replace with your own hostname
      - "traefik.http.routers.freshrss.rule=Host(`rss.my-example.com`)"
      - "traefik.http.routers.freshrss.entrypoints=websecure"
      - "traefik.http.routers.freshrss.tls.certresolver=mydnschallenge"
      - "traefik.docker.network=traefik"
      - "traefik.http.middlewares.freshrss.headers.stsSeconds=311040000"
      - "traefik.http.middlewares.freshrss.headers.stsIncludeSubdomains=true"
      - "traefik.http.middlewares.freshrss.headers.stsPreload=true"
    networks:
      - traefik
      - default
    logging:
      driver: "json-file"
      options:
        max-file: "2"
        max-size: "500k"

volumes:
  freshrss_pgdata:
    driver_opts:
      type: none
      o: bind
      device: ${HOME}/volumes/freshrss/postgres
  freshrss_data:
    driver_opts:
      type: none
      o: bind
      device: ${HOME}/volumes/freshrss/data
  freshrss_extensions:
    driver_opts:
      type: none
      o: bind
      device: ${HOME}/volumes/freshrss/extensions

networks:
  traefik:
    external:
      name: traefik

如果您了解 Docker-Compose 的语法,并且结合上篇文章对 Traefik 的介绍,上面的配置文件应该是 Self-explanatory 的,不需要太多解释。

有几个 Tips 值得一提:

  1. 这个配置没有指定 FreshRSS 的版本,也就是每次运行 docker-compose pull 拉取镜像时都会拉取当时的最新 latest 版本。如果数据文件是旧的(因为已经持久化在硬盘上了)而 FreshRSS 程序本身更新了(因为新拉取的镜像),则有极小的可能出现不兼容问题。如果十分在意版本稳定的话,可以手动指定 FreshRSS 镜像的版本。
  2. 我们创建 3 个 volumes 对 FreshRSS 的 dataextensions 文件夹和 PostgreSQL 数据库的 data 文件夹进行持久化。这 3 个 volumes 对应的文件夹在服务器硬盘上的实际位置,在 device: 字段后面有写。
  3. PostgreSQL 镜像的用户名和密码等信息可以改成你自己的。当然用简单密码也不见得就不安全,毕竟这个数据库容器只与 FreshRSS 容器通信,而不会暴露给外界。
  4. 我们指定了 PostgreSQL 镜像的版本为 12. 因为 PostgreSQL 的版本号有大版本(major version)和小版本(minor version)两个部分,例如 12.2,major version 12,minor version 是 1. 小版本更新是向下兼容的,例如 12.3 可以直接沿用 12.1 留下来的数据文件夹。但是大版本更新则可能不兼容,例如 PostgreSQL 13 可能无法直接打开 PostgreSQL 12.3 的数据文件夹,需要人工处理。这里为了防止出现 PostgreSQL 镜像从 12.x 自动更新成 13.x 的情况,我们限制其大版本号。

最后,在 docker-compose.yml 所在目录下,运行

docker-compose up -d

启动镜像。

初始化

如果是初次创建 FreshRSS 容器的话,与上一篇的 whoami 一样,需要稍等一会儿,等申请的 HTTPS 证书成功部署。然后就可以访问你的网址 https://rss.my-example.com 开始初始化设置了。

  1. 第一次进入搭建好的 FreshRSS 网页版,开始初始化设置。 FreshRSS-Init-1
  2. 系统自检,理论上应该都是 Okay! FreshRSS-Init-2
  3. 数据库的 Host 填写刚才 PostgreSQL 数据库容器的服务名即可,也就是 docker-compose.yml 里面定义的那个 freshrss_postgresql:,不含冒号。 FreshRSS-Init-3
  4. 创建第一个用户。 FreshRSS-Init-4
  5. FreshRSS-Init-5

之后就大功告成了,到处看看,体验一下网页版,浏览一遍可用的系统设置:FreshRSS-Init-6

我们需要允许 API 访问,这样才可以使用 Reeder 等客户端软件连接 FreshRSS 服务器:

  1. 作为管理员(也就是初始化时创建的那个用户)登录,在网页版 FreshRSS 右上角系统设置,点击 Authentication勾选 Allow API access
  2. Profile 选项页中,下方 API management 处,设置一个 API Password。这个 Password 是 RSS 客户端连接时用的,与网页版登录密码可以相同页可以不同。设置密码的时候,下面有一个 API 说明的连接,记得点开看看。如果 Google Reader API 和 Fever API 两项都显示 ✓PASS,则恭喜你的服务器一切正常。记下这两个 API 的地址。

SMTP 设置(可选)

新装好的 FreshRSS 可以配置 SMTP,使服务器可以向用户发送邮件。如果您希望自己的服务器对外开放注册,同时希望注册的用户必须验证完自己的 Email 地址才可以开始使用服务,则需要配置 FreshRSS 服务器的 SMTP 功能。

方法是编辑 data 目录(按照我们上面的 convention,这个目录是 ${HOME}/volumes/freshrss/data)下的 config.php,找到 mailer 开头的那一段:

# config.php

# Configuration to send emails. Be aware that PHP < 5.5 are not supported.
# These options are basically a mapping of the PHPMailer class attributes
# from the PHPMailer library.
#
# See http://phpmailer.github.io/PHPMailer/classes/PHPMailer.PHPMailer.PHPMailer.html#properties
'mailer' => 'mail', // 'mail' or 'smtp'
'smtp' => array(
  'hostname' => '', // the domain used in the Message-ID header
  'host' => 'localhost', // the SMTP server address
  'port' => 25,
  'auth' => false,
  'auth_type' => '', // 'CRAM-MD5', 'LOGIN', 'PLAIN', 'XOAUTH2' or ''
  'username' => '',
  'password' => '',
  'secure' => '', // '', 'ssl' or 'tls'
  'from' => 'root@localhost',
),

# ...

照着文档把相关字段改成自己的就可以。我用的是 Mailgun 的 SMTP 服务。这家服务商可以提供 GitHub Student Developer Pack 优惠。

配置客户端软件

这里有一份 RSS 软件们对 FreshRSS 的兼容性列表。

我们以 macOS 或 iOS 平台的 Reeder 为例。其他客户端的配置方法大同小异。添加 FreshRSS 账户,服务器地址填写 https://<你的 FreshRSS 服务器地址>/api/greader.php,其实就算没写后面的 /api/greader.php 这部分,Reeder 也能自动识别出来。密码填写上面设置的 API Password。

之后就可以用客户端刷 RSS 了。

Extensions 插件

FreshRSS 服务端可以添加插件来扩展其功能,例如添加邮件分享按钮、阅读耗时估计、自定义 CSS 样式等。要添加插件,只需要将插件的目录下载到服务器上,放置在 FreshRSS 安装目录下的 extensions 文件夹中即可。对于我们部署的运行在 Docker 容器中的 FreshRSS 而言,extensions 文件夹在 Host 机器上对应的路径是 ~/volumes/freshrss.extensions

文件复制好之后(可能要 docker-compose restart freshrss 重启一下容器?),进入 FreshRSS 的 Web UI,在系统设置中启用插件即可。

FreshRSS-Extensions