AI 新闻雷达封面

图:Docker 自托管 Horizon,把 RSS、GitHub 等信息流聚合成每日 AI 简报,并通过 cpolar 在外网安全查看。

你的专属 AI 新闻雷达:Docker 自托管 RSS/GitHub 聚合器,用 cpolar 随时查看每日简报

每天打开几十个信息源,很容易越看越乱:GitHub Trending、RSS、Hacker News、Telegram 频道、AI 工具更新,全都值得看,但人的注意力就那么一点。

我更喜欢把这类事情交给一个固定流程:让工具每天抓取、去重、打分、生成简报,我只看筛出来的结果。这篇就用 HelloGitHub 上榜的 Horizon 搭一个个人 AI 新闻雷达,再用 cpolar 给简报页面开一个外网入口。人在公司、路上、手机上,都能看当天简报,不用把 NAS 后台直接暴露出去。

这不是把 cpolar 当主角。Horizon 负责信息聚合和 AI 简报,cpolar 只负责“需要从外面看一眼”的入口。

1 什么是 Horizon?这篇里它负责什么

Horizon 是 Thysrael 开源的 AI 新闻雷达工具。HelloGitHub 页面给出的描述很直接:它支持从 Hacker News、Reddit、RSS、Telegram、GitHub 等渠道获取内容,经过去重、AI 打分筛选、背景信息补充和摘要生成后,产出中英文每日简报。

选题报告里也记录了它在 HelloGitHub 的热度:hot=10052,项目描述命中“AI 驱动个人新闻聚合与简报生成”。这类工具适合开发者做自己的信息入口,尤其是 AI、开源项目、工具链更新这种高频变化的方向。

在这篇教程里,Horizon 只承担三件事:

  • 抓取 RSS、Hacker News、GitHub 等来源;
  • 用大模型给条目打分、去重、整理摘要;
  • 把结果保存成 Markdown 简报,放到本机目录里。

简报生成之后,我们再额外跑一个只读 Nginx,把 data/summaries 目录发布成网页。这里别直接开放 NAS、Docker 面板或 SSH,入口越小,后面排错和安全控制越轻松。

Horizon 多源聚合流程

图:Horizon 将 RSS、GitHub、Hacker News、Telegram 等来源汇入统一流程,经过去重、AI 打分和摘要整理后生成每日简报。

看到这张图时,读者应该能确认:Horizon 的主线是“多源输入 → 去重打分 → 生成简报 → 投递/发布”,不是单纯的 RSS 阅读器。

2 环境准备:Docker、Git 和 API Key

这套方案适合放在家用服务器、NAS、云主机或一台长期在线的小主机上。只要机器能跑 Docker,并且能访问你配置的信息源,就能按下面流程走。

2.1 安装基础工具

以 Ubuntu / Debian 系统为例,先准备 Git、Docker 和 Docker Compose 插件:

sudo apt update
sudo apt install -y git ca-certificates curl
curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker $USER
newgrp docker
docker version
docker compose version

这里建议执行完 newgrp docker 再继续,不然当前终端里仍然要加 sudo。如果 docker compose version 没输出版本号,先检查 Docker 是否安装完整,不要急着拉项目。

2.2 准备一个 AI API Key

Horizon 的示例配置支持 OpenAI、Anthropic、Gemini、DeepSeek、Doubao、MiniMax、Ollama 以及 OpenAI-compatible API。为了让教程更聚焦,下面用 OpenAI-compatible 写法演示,你也可以换成自己正在用的供应商。

注意:API Key 只写进 .env,不要直接写进 data/config.json。Horizon 的配置示例里也明确说明,api_key_env 填的是环境变量名,不是密钥本身。

mkdir -p ~/apps
cd ~/apps
git clone https://github.com/Thysrael/Horizon.git
cd Horizon
cp .env.example .env
cp data/config.example.json data/config.json

打开 .env,至少保留并填写一个可用的 Key:

OPENAI_API_KEY=sk-your-key
GITHUB_TOKEN=ghp_your-token
HORIZON_WEBHOOK_URL=

GITHUB_TOKEN 不是硬性必填,但建议配上。GitHub 未认证请求每小时 60 次,带 token 后官方 API 额度更充足,抓 GitHub 用户事件和 Release 时更稳。

3 用 Docker 跑一次 Horizon,先确认简报能生成

现在不要急着做外网访问。先让 Horizon 在本机跑通一次,这一步不是为了测试而测试,而是确认“源能抓到、模型能调用、文件能落盘”。

3.1 精简配置来源

官方示例配置很全,包含 GitHub、Hacker News、RSS、Reddit、Twitter/X、OpenBB 等来源。新手第一次跑,建议先保留 RSS、Hacker News、GitHub 三类,少一点信息源,错误也更好定位。

data/config.json 调整成下面这份可运行的精简配置:

{
  "version": "1.0",
  "ai": {
    "provider": "openai",
    "model": "gpt-4",
    "api_key_env": "OPENAI_API_KEY",
    "temperature": 0.3,
    "max_tokens": 4096,
    "throttle_sec": 0,
    "analysis_concurrency": 1,
    "enrichment_concurrency": 1
  },
  "sources": {
    "github": [
      {
        "type": "repo_releases",
        "owner": "astral-sh",
        "repo": "uv",
        "enabled": true
      }
    ],
    "hackernews": {
      "enabled": true,
      "fetch_top_stories": 20,
      "min_score": 100
    },
    "rss": [
      {
        "name": "Simon Willison",
        "url": "https://simonwillison.net/atom/everything/",
        "enabled": true,
        "category": "ai-tools"
      }
    ],
    "reddit": {
      "enabled": false,
      "subreddits": [],
      "users": [],
      "fetch_comments": 0
    },
    "twitter": {
      "enabled": false,
      "users": [],
      "fetch_limit": 0,
      "fetch_reply_text": false,
      "max_replies_per_tweet": 0,
      "max_tweets_to_expand": 0,
      "reply_min_likes": 0
    },
    "openbb": {
      "enabled": false,
      "fetch_filings": false,
      "filings_provider": "sec",
      "watchlists": []
    },
    "ossinsight": {
      "enabled": false,
      "period": "past_24_hours",
      "languages": ["All"],
      "keywords": [],
      "min_stars": 10,
      "max_items": 30
    }
  },
  "filtering": {
    "ai_score_threshold": 6.0,
    "time_window_hours": 24,
    "max_items": 10,
    "category_groups": {},
    "default_group": "other",
    "default_group_limit": null
  },
  "webhook": {
    "enabled": false,
    "url_env": "HORIZON_WEBHOOK_URL",
    "delivery": "summary",
    "overview_position": "first",
    "platform": "generic",
    "layout": "markdown",
    "fallback_layout": "markdown",
    "languages": null,
    "request_body": {},
    "headers": ""
  }
}

这里别把 ai_score_threshold 一上来调得太高。先用 6.0 看结果,确认能产出简报后,再根据自己的口味收紧。

3.2 执行一次生成任务

Horizon 仓库自带 Docker Compose 配置,官方 README 给出的 Docker 运行方式是:

docker compose run --rm horizon

如果你想抓最近 48 小时的内容,也可以这样跑:

docker compose run --rm horizon --hours 48

运行结束后检查简报目录:

ls -lah data/summaries
find data/summaries -maxdepth 1 -type f | sort | tail -5

能看到 Markdown 文件,就说明简报已经落盘。如果目录为空,先看终端日志里的报错:Key 错、模型名不支持、RSS 源访问失败、GitHub API 额度不足,是最常见的四类问题。

Docker 运行 Horizon 并生成简报

图:先在 Docker 中跑通 Horizon,再确认 data/summaries 目录已经生成 Markdown 简报文件。

这一步截图要让读者看到两件事:容器任务已经跑完,data/summaries 目录里有新生成的简报文件。

4 用 Nginx 发布只读简报页面

Horizon 默认把简报保存到本地目录。手机想看,就需要一个 Web 页面。这里我不建议直接折腾 Horizon 本身的输出链路,先加一个只读 Nginx,简单、清晰、出问题也好查。

在项目根目录新建 compose.viewer.yml

cat > compose.viewer.yml <<'EOF'
services:
  horizon-viewer:
    image: nginx:1.27-alpine
    container_name: horizon-viewer
    ports:
      - "8088:80"
    volumes:
      - ./data/summaries:/usr/share/nginx/html:ro
    restart: unless-stopped
EOF

启动查看页面:

docker compose -f compose.viewer.yml up -d
docker ps --filter name=horizon-viewer
curl -I http://127.0.0.1:8088/

浏览器打开:

http://服务器IP:8088/

如果页面显示 Nginx 的目录列表或简报文件名,说明只读页面已经能访问。这里有个小提醒:Nginx 只挂载 data/summaries,不要把整个项目目录挂进去,.env 里有 API Key,不能让它出现在网页目录里。

如果访问不到,按这个顺序查:

docker logs horizon-viewer --tail 50
ss -lntp | grep 8088
ls -lah data/summaries

8088 没监听,就看容器是否启动;目录里没文件,就回到第 3 节重新跑一次 Horizon。

5 加一个定时任务,每天自动生成简报

手动跑通之后,再加定时任务。这里用宿主机 cron,原因很简单:命令清楚,日志好找,NAS 和 Linux 小主机都容易迁移。

先写一个运行脚本:

cat > run-horizon.sh <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
cd "$HOME/apps/Horizon"
docker compose run --rm horizon --hours 24
EOF
chmod +x run-horizon.sh

手动执行一次:

./run-horizon.sh

确认脚本没问题后,加入 crontab,每天早上 8 点执行:

(crontab -l 2>/dev/null; echo "0 8 * * * $HOME/apps/Horizon/run-horizon.sh >> $HOME/apps/Horizon/horizon-cron.log 2>&1") | crontab -
crontab -l

这里别把时间设得太密。新闻简报一天跑一次就够了,频率太高会增加 API 调用和信息噪音。真要临时补抓,手动执行 ./run-horizon.sh 更稳。

6 用 cpolar 随时查看每日简报

局域网里能打开 http://服务器IP:8088/ 后,再考虑外网入口。cpolar 在这里的作用很明确:把 8088 这个只读简报页面映射出去,给手机或同事临时查看。

6.1 安装并登录 cpolar

cpolar 官方文档给出的 Linux 一键安装命令如下:

curl -L https://www.cpolar.com/static/downloads/install-release-cpolar.sh | sudo bash

安装完成后,检查版本和本地 Web UI:

cpolar version
curl -s http://127.0.0.1:9200 || echo "cpolar Web UI 未启动"

打开本机管理页面:

http://127.0.0.1:9200

有图形界面的环境,直接在 Web UI 登录 cpolar 账号。纯命令行环境可以手动绑定 authtoken:

cpolar authtoken <你的 authtoken>

这里别把 9200 端口也暴露出去。9200 是 cpolar 本地管理入口,这篇只需要暴露简报页面的 8088

6.2 创建 HTTP 隧道映射 8088

临时查看简报,用命令行开 HTTP 隧道就够了:

cpolar http 8088

终端会输出一个公网访问地址。把这个地址发到手机浏览器里打开,就能看到 data/summaries 里的简报文件。

如果你更习惯 Web UI,也可以在 http://127.0.0.1:9200 创建隧道:

  • 隧道名称:horizon-viewer
  • 协议:http
  • 本地地址:8088
  • 域名类型:免费套餐选择随机域名
  • 地区:按需选择

创建后到“状态 → 在线隧道列表”查看公网地址。免费随机地址适合临时演示,cpolar 已核对口径是:免费套餐生成的公网地址为随机临时地址,24 小时内会变化。

如果你要把这个地址固定下来,用固定二级子域名更合适。cpolar 已核对规则是:固定二级子域名需要基础套餐或以上;自定义域名需要专业套餐或以上。团队每天都看同一个简报入口时,固定地址能省掉反复改链接的麻烦。

cpolar 映射只读简报页面

图:cpolar 只映射 Nginx 的 8088 简报页面,让手机或同事从外网查看,不暴露 NAS、Docker 或 SSH 后台。

这张图要让读者看到公网地址已经生成,并且本地映射端口是 8088,不是 NAS 后台端口。

7 安全提醒:只公开简报,不公开后台

这类工具最容易踩的坑,不是 Docker 跑不起来,而是顺手把不该公开的东西也放出去了。

建议按下面几条做:

  • 只映射 horizon-viewer8088,不要映射 Docker、NAS、SSH、cpolar Web UI;
  • .env 不进 Web 目录,API Key 只放在项目根目录;
  • 临时给同事看,用完就停掉 cpolar http 8088
  • 长期固定入口,给简报页加一层基础认证或放到受控访问环境里。

如果你只是自己在局域网里用,第 6 节可以先跳过。等出差、通勤、临时分享时,再开 cpolar 隧道也不迟。

停掉查看页面也很简单:

docker compose -f compose.viewer.yml down

停掉临时 cpolar 隧道,回到运行 cpolar http 8088 的终端,按 Ctrl+C 即可。

8 总结

这套流程跑完后,你已经把一个开源 AI 新闻雷达部署到了自己的机器上:Horizon 每天抓取 RSS、Hacker News、GitHub 等来源,生成 Markdown 简报;Nginx 把简报目录变成只读页面;cpolar 在需要外网查看时提供入口。

关键步骤可以记成三段:

  • Horizon 负责信息处理:配置来源、填写 API Key、执行 docker compose run --rm horizon
  • Nginx 负责只读展示:只挂载 data/summaries,用 8088 对内访问;
  • cpolar 负责外网入口:临时用随机地址,长期使用固定二级子域名或自定义域名。

我比较推荐先从“每天一份简报”开始,不要一上来把所有平台都接满。等你确认哪些 RSS、GitHub 仓库和社区来源真的有价值,再慢慢调高筛选阈值、加 webhook 或团队通知。信息雷达好不好用,关键不是抓得多,而是每天打开时,里面真的有你愿意读的东西。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐