图: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 将 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,再确认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/summaries8088没监听,就看容器是否启动;目录里没文件,就回到第 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 只映射 Nginx 的8088简报页面,让手机或同事从外网查看,不暴露 NAS、Docker 或 SSH 后台。
这张图要让读者看到公网地址已经生成,并且本地映射端口是8088,不是 NAS 后台端口。
7 安全提醒:只公开简报,不公开后台
这类工具最容易踩的坑,不是 Docker 跑不起来,而是顺手把不该公开的东西也放出去了。
建议按下面几条做:
- 只映射
horizon-viewer的8088,不要映射 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 或团队通知。信息雷达好不好用,关键不是抓得多,而是每天打开时,里面真的有你愿意读的东西。