群晖自部署Omnivore服务

2025年7月16日 · 2278

前言

稍后读(Read It Later)服务近一年来的发展似乎并不怎么好

  • 2024年11月5日,Omnivore被 ElevenLabs 收购,不再对外提供服务;
  • 2025年7月8日,老牌阅后读软件Pocket即将停止服务

随着网页技术越来越碎片化,各家对自己的内容也增加了很多限制——反爬、动态加载等等,都让内容解析难度不断提升,成本也在不断增加。再者就是付费意愿低,各大厂商都有自己的“阅后读”功能——书签、收藏——阅后读是否还真的需要呢?

自部署

WHY

omnivore虽然被收购,但是其项目还是开源状态,也一直在不断更新,可以进行自部署。配套的手机软件、网页插件等都可以正常使用。 在折腾之前,也使用过其他类似软件,例如Cubox、Readwise、RainDrop包括Flomo等,都挺不错,但是都有长有短。

  • CuBox和ReadWise都是商业软件,订阅费说贵倒是确实不贵,但是秉承良好持家的传统,以及家里还有一台NAS不用白不用的心态,我更倾向自己部署服务;
  • 其次,非自部署的服务,我的所有数据都无法保证持久化,万一哪天关了数据就没了,自己手里拿着总归是更稳妥的;

omnivore的官方部署文档写的其实挺完备,但是依旧还是有一些坑需要踩,尤其是你的部署环境比较复杂的时候。omnivore的部署本身不复杂,麻烦的地方在于它的服务太多了,整个项目下来有11个容器,我群晖上跑着的拢共也才十个😅 omnivore全部服务

多了之后,带来的另一个问题就是对系统要求提高了,正常运行下内存占用大概在700MB左右,如果订阅RSS较多、且内容抓取解析的数量一大,内存占用可能高达2GB。网上自部署这个项目的文章和教程也比较少,大概这也是原因之一。

克隆项目

  • 根据官方文档,首先将项目克隆到本地;
  • 来到 self-hosting/docker-compose 这个文件夹;
  • 这里你会看到一个 docker-compose.yaml 文件,里面是全部需要的镜像;
  • 还有一个 .env.example 的环境变量,将其复制重命名为 .env ,这样就会被项目正确读取;

docker配置文件修改

众所周知的原因,docker服务在国内有时候不太顺,所以在执行镜像拉取的时候会经常出现网络问题导致失败。我对官方的配置文件进行了修改,主要调整了三个地方:

  • 修改ghio的镜像地址,由ghcr.io改为ghcr.nju.edu.cnghcr.io是github的镜像,ghcr.nju.edu.cn是国内南京大学的镜像源,速度更快
  • 修改默认docker的镜像地址,将redis minio 改为docker.1ms.run 这个镜像;
  • 修改持久化地址,默认是会有三个data文件夹,pgdata redis_data minio_data,我将其修改成为自定义文件夹地址,方便管理; 完整配置文件如下:
version: '3'
x-postgres:
  &postgres-common
  image: "docker.1ms.run/ankane/pgvector:v0.5.1"
  user: postgres
  healthcheck:
    test: "exit 0"
    interval: 2s
    timeout: 12s
    retries: 3

services:
  postgres:
    <<: *postgres-common
    container_name: "omnivore-postgres"
    volumes:
      # 这里进行了自定义文件夹设置,注意进行修改
      - /docker/omnivore/data/pgdata:/var/lib/postgresql/data
    env_file:
      - .env

  migrate:
    image: "ghcr.nju.edu.cn/omnivore-app/sh-migrate:latest"
    container_name: "omnivore-migrate"
    command: '/bin/sh ./packages/db/setup.sh' # Also create a demo user with email: demo@omnivore.app, password: demo_password
    env_file:
      - .env
    depends_on:
      postgres:
        condition: service_healthy

  api:
    image: "ghcr.nju.edu.cn/omnivore-app/sh-backend:latest"
    container_name: "omnivore-api"
    ports:
      - "4000:8080"
    healthcheck:
      test: ["CMD-SHELL", "nc -z 0.0.0.0 8080 || exit 1"]
      interval: 15s
      timeout: 90s
      retries: 6
    env_file:
      - .env
    depends_on:
      migrate:
        condition: service_completed_successfully

  queue-processor:
    image: "ghcr.nju.edu.cn/omnivore-app/sh-queue-processor:latest"
    container_name: "omnivore-queue-processor"
    env_file:
      - .env
    depends_on:
      api:
        condition: service_started

  web:
    image: "ghcr.nju.edu.cn/omnivore-app/sh-web:latest"
    container_name: "omnivore-web"
    ports:
      - "53888:8080"
    env_file:
      .env
    depends_on:
      api:
        condition: service_healthy

  image-proxy:
    image: "ghcr.nju.edu.cn/omnivore-app/sh-image-proxy:latest"
    container_name: "omnivore-image-proxy"
    ports:
      - "7070:8080"
    env_file:
      - .env

  content-fetch:
    image: "ghcr.nju.edu.cn/omnivore-app/sh-content-fetch:latest"
    container_name: "omnivore-content-fetch"
    ports:
      - "9090:8080"
    environment:
      - USE_FIREFOX=true # Using Firefox here because the official chrome version seems to freeze a lot in Docker.
    env_file:
      - .env
    depends_on:
      redis:
        condition: service_healthy
      api:
        condition: service_healthy

  redis:
    image: "docker.1ms.run/redis:7.2.4"
    container_name: "omnivore-redis"
    expose:
      - 6379
    ports:
      - "6379:6379"
    healthcheck:
      test: [ "CMD", "redis-cli", "--raw", "incr", "ping" ]
    volumes:
      # 这里进行了自定义文件夹设置,注意进行修改
      - /docker/omnivore/data/redis_data:/data

  minio:
    image: docker.1ms.run/minio/minio
    expose:
      - 1010
    ports:
      - "1010:9000"
    healthcheck:
      test: [ "CMD", "mc", "ready", "local" ]
      interval: 5s
      timeout: 1s
    environment:
      - "MINIO_ACCESS_KEY=minio"
      - "MINIO_SECRET_KEY=miniominio"
      - "AWS_S3_ENDPOINT_URL=http://minio:1010"
    command: server /data
    volumes:
      # 这里进行了自定义文件夹设置,注意进行修改
      - /docker/omnivore/data/minio_data:/data

  createbuckets:
    image: docker.1ms.run/minio/mc
    environment:
      - MINIO_ACCESS_KEY=minio
      - MINIO_SECRET_KEY=miniominio
      - BUCKET_NAME=omnivore
      - ENDPOINT=http://minio:9000
      - AWS_S3_ENDPOINT_URL=http://minio:9000
    depends_on:
      - minio
    entrypoint: >
      /bin/bash -c "
      sleep 5;
      until (/usr/bin/mc config host add myminio http://minio:9000 minio miniominio) do echo '...waiting...' && sleep 1; done;
      /usr/bin/mc mb myminio/omnivore;
      /usr/bin/mc anonymous set public myminio/omnivore;
      exit 0;
      "
  mail-watch-server:
    image: "ghcr.nju.edu.cn/omnivore-app/sh-local-mail-watcher:latest"
    container_name: "omnivore-mail-watch-server"
    ports:
      - "4398:8080"
    env_file:
      - .env
    depends_on:
      redis:
        condition: service_healthy

env环境变量修改

主要修改的是下面这几个URL,需要注意的是,如果你需要进行反代并将服务绑定域名,那么一定要注意端口的问题。 假设你最终将服务绑定到域名 omnivore.my.com,那么相关地址全都要修改,并且注意不用带端口号;此外就是需要通过nginx进行反代,将一些子链接进行转发;

环境变量描述Local Parameter自部署地址
BASE URL应用的前端基础地址http://localhost:3000omnivore.my.com
SERVER_BASE_URLAPI服务的地址http://localhost:4000omnivore.my.com
HIGHLIGHTS_BASE_URL前端高亮服务的地址http://localhost:3000omnivore.my.com
CLIENT_URL客户端的地址http://localhost:3000omnivore.my.com
IMAGEPROXY_URL镜像代理的地址http://localhost:7000omnivore.my.com

Nginx反代

我使用的是Nginx Proxy Manager,有UI界面,但原理一样; 在 Proxy Host 新增一个host,写入你的域名和本地服务地址——例如本地地址是192.168.3.1,端口是3000NPM设置

而后,在 Advanced选项,增加对子链接的反代配置;这样就完成啦;

location /api/client/auth {
    proxy_pass http://192.168.3.1:3000;
}

location /api/save {
    proxy_pass http://192.168.3.1:3000;
}

location /api {
    proxy_pass http://192.168.3.1:4000;
}

location /mail {
    proxy_pass http://192.168.3.1:4398/mail;
}

location /bucket {
    proxy_pass http://192.168.3.1:1010;
}

location /images {
    proxy_pass http://192.168.3.1:7070;
}

location / {
    proxy_pass http://192.168.3.1:3000;
}

运行服务

终端部署

正常情况下,通过 SSH 连接到服务器,在docker-compose.yaml所在文件夹,运行

docker compose up -d

# 如果你的docker服务版本较低,需要运行下面这个命令
# docker-compose up -d 

然后就能看到镜像开始拉取和安装,全部完成后,即可直接访问;

群晖部署

群晖自带的 ContainerManager 提供了可视化的 docker compsoe 部署,更加方便快捷。 首先打开 ContainerManager ,点击左侧 项目,然后点击新增。把路径选择为你实际的 docker-compose.yaml 所在的地址,它会自动识别到配置文件,选择确定。 而后进入项目,点击右上角的 创建,就能看到窗口的镜像拉取日志了,此时可以关闭挂机一段时间,等全部镜像拉取启动完成后,大功告成~ 新建配置

登录

服务全部启动成功后,在群晖的项目设置会看到提示,有一个 omnivore-migrate 没有运行,这是正常的,它是一个迁移服务,在一开始会创建默认的账户及密码,随后就会自动关闭;当然你也可以选择在登录页面自行创建账号进行登录。

  • 默认账号:demo@omnivore.app
  • 默认密码:demo_passowrd

体验

支持的功能和特性其实挺多,包括RSS的订阅、内容抓取解析、还有对Email的支持等,在阅读时候可以进行高亮、笔记、打标签,基本上该有的都有了。作为一个自部署的服务他已经很棒了

omnivore首页界面

阅读可进行笔记和高亮

疑惑

但我还有几个地方没有找到如何修改

  • 语言选项,我始终是英文状态,导致我订阅的 HelloGithub 给我发来的月刊都是英文的;
  • RSS 的订阅刷新频次,没有看到相关的设置,也不知道啥时候会刷新;
  • 自定义字体,目前都是英文字体,我想进行自定义字体的设置;

如果有解决方式的话,希望不吝赐教。


参考链接: