143 lines
5.9 KiB
Markdown
143 lines
5.9 KiB
Markdown
# Daily News Digest
|
||
|
||
这是一个面向个人服务器的资讯日报项目,第一阶段不接入 AI:n8n 负责定时抓取 RSS,按关键词分类、去重并写入 PostgreSQL;网页读取 PostgreSQL 展示当天和历史记录;邮件发送当天完整日报。
|
||
|
||
## 当前范围
|
||
|
||
- AI 与 Agent
|
||
- 农业硬件
|
||
- 农业方案落地
|
||
- 农业服务
|
||
- 政策与市场
|
||
- 国内与国际资讯
|
||
|
||
## 数据库初始化
|
||
|
||
1. 在 PostgreSQL 中创建一个独立数据库和用户,例如 `news_digest` / `news_app`。
|
||
2. 使用 `db/schema.sql` 建表:
|
||
|
||
```bash
|
||
psql -h 127.0.0.1 -p 15432 -U news_app -d news_digest -f db/schema.sql
|
||
```
|
||
|
||
Windows PowerShell 示例:
|
||
|
||
```powershell
|
||
psql -h 127.0.0.1 -p 15432 -U news_app -d news_digest -f .\db\schema.sql
|
||
```
|
||
|
||
如果 PostgreSQL 不在本机,先建立 SSH 隧道:
|
||
|
||
```bash
|
||
ssh -N -L 15432:127.0.0.1:5432 <ssh-user>@<server-ip>
|
||
```
|
||
|
||
这会把本机 `127.0.0.1:15432` 转发到 SSH 服务器可访问的 `127.0.0.1:5432`。数据库本身不需要暴露公网端口。
|
||
|
||
## Docker 中访问 SSH 隧道
|
||
|
||
如果 n8n 或网页容器运行在 Docker 中,容器里的 `127.0.0.1` 指向容器自身,不是宿主机。此时:
|
||
|
||
- Linux Docker:让隧道监听宿主机地址,并将 `host.docker.internal` 映射到宿主机网关;
|
||
- Docker Desktop:通常可直接使用 `host.docker.internal`;
|
||
- `.env` 中的 `PGHOST` 应填写 `host.docker.internal`,`PGPORT` 填写隧道本地端口(默认 `15432`)。
|
||
|
||
本项目不会自动保存或生成 SSH 私钥。建议使用 systemd、Windows 服务或 Docker sidecar 管理 SSH 隧道,并为隧道设置自动重连。
|
||
|
||
Linux 云服务器上推荐使用 `docker-compose.host-network.yml`:SSH 隧道监听宿主机 `127.0.0.1:15432`,网页容器使用宿主机网络,`.env` 中填写 `PGHOST=127.0.0.1`、`PGPORT=15432`。这样不会把数据库隧道端口暴露到公网。模板见 `deploy/daily-news-db-tunnel.service.example`。
|
||
|
||
网页服务可由 Nginx 代理到宿主机本地端口。使用 `docker-compose.host-network.yml` 时,覆盖配置会让网页只监听 `127.0.0.1:3100`;不要直接把 3100 暴露给公网。
|
||
|
||
## 配置
|
||
|
||
复制 `.env.example` 为 `.env`,再在服务器上填写实际值。仓库中不提交 `.env`、密码、SMTP 授权码或 SSH 私钥。
|
||
|
||
## 当前完成度
|
||
|
||
- 网页日报和历史查询已完成
|
||
- 收件邮箱、多模块订阅设置已完成
|
||
- PostgreSQL 访问层和 Docker 部署配置已完成
|
||
- n8n RSS 抓取、日报生成和 SMTP 发送工作流待接入
|
||
|
||
网页和邮件会读取同一份 PostgreSQL 数据,因此当天内容与历史记录保持一致。
|
||
|
||
`news_articles.category` 用于主要栏目;`news_articles.topics` 支持一篇文章同时标记多个主题,例如同时属于 `ai_agent` 和 `agri_solutions`。历史搜索由网页服务使用 `ILIKE` 查询标题、摘要和关键词,避免依赖 PostgreSQL 内置的中文分词。
|
||
|
||
外文翻译是可选的独立步骤,不等同于 AI 内容分析。`news_articles.title` 和 `summary` 保留原文;`translated_title` 和 `translated_summary` 保存中文翻译。`translation_status` 记录是否翻译成功。翻译服务可以使用阿里云机器翻译、DeepL、Google Cloud Translation,或以后改成本地翻译服务;API 密钥只放在服务器 `.env` 中。
|
||
|
||
## 用户和邮件订阅
|
||
|
||
`app_users` 保存网页用户账号;密码只保存 Argon2id/bcrypt 哈希,不保存明文密码。`newsletter_recipients` 保存实际收件邮箱,`recipient_modules` 是邮箱与模块的多对多关系,因此一个邮箱可以选择多个模块。`newsletter_modules` 是可扩展的模块目录。
|
||
|
||
如果原始 `schema.sql` 已经执行过,请按顺序执行:
|
||
|
||
```text
|
||
db/migrations/002_users_and_subscriptions.sql
|
||
db/migrations/003_translation_fields.sql
|
||
```
|
||
|
||
不要为了增加用户功能删除已有表。以后新环境从零创建时,直接执行完整的 `db/schema.sql` 即可。
|
||
|
||
示例:创建一个收件邮箱并订阅多个模块:
|
||
|
||
```sql
|
||
INSERT INTO newsletter_recipients (email, display_name)
|
||
VALUES ('your@example.com', '我的日报')
|
||
RETURNING id;
|
||
|
||
-- 将上一步返回的 id 替换为 1
|
||
INSERT INTO recipient_modules (recipient_id, module_key)
|
||
VALUES
|
||
(1, 'ai_agent'),
|
||
(1, 'agri_solutions'),
|
||
(1, 'agri_services');
|
||
```
|
||
|
||
## Gitea 部署方式
|
||
|
||
项目完成后,将整个 `daily-news-digest` 目录作为一个独立仓库推送到 Gitea。服务器只保存运行所需的工作副本,实际配置文件 `.env` 在服务器本地填写,不提交到 Gitea。
|
||
|
||
推荐的第一阶段流程:
|
||
|
||
```text
|
||
本地修改
|
||
↓
|
||
提交并推送到 Gitea
|
||
↓
|
||
服务器 git pull
|
||
↓
|
||
docker compose up -d --build
|
||
```
|
||
|
||
使用 Linux 主机网络时改为:
|
||
|
||
```bash
|
||
docker compose -f docker-compose.yml -f docker-compose.host-network.yml up -d --build
|
||
```
|
||
|
||
后续如果启用 Gitea Actions 或 Woodpecker CI,可以把最后两步自动化;在当前没有业务代码、需要先稳定运行的阶段,先采用服务器手动拉取更新更容易排错。
|
||
|
||
服务器首次部署时大致是:
|
||
|
||
```bash
|
||
git clone <你的 Gitea 仓库地址> /opt/daily-news-digest
|
||
cd /opt/daily-news-digest
|
||
cp .env.example .env
|
||
# 只在服务器本地填写 .env
|
||
docker compose up -d --build
|
||
```
|
||
|
||
SSH 隧道、PostgreSQL 密码、SMTP 授权码都不放进仓库;Gitea 只管理源码、SQL、工作流模板和部署文件。
|
||
|
||
## 网页和收件人设置
|
||
|
||
网页服务默认监听 `3000` 端口。部署前在服务器 `.env` 中填写:
|
||
|
||
```env
|
||
APP_ADMIN_TOKEN=请设置一个随机的长令牌
|
||
```
|
||
|
||
打开 `/settings` 后输入这个令牌,即可添加、编辑和删除收件邮箱,并为每个邮箱选择一个或多个推送模块。令牌只保存在当前浏览器会话中;没有配置令牌时,邮箱管理接口会拒绝请求。
|
||
|
||
日报页面地址为 `/`,设置页面地址为 `/settings`。网页只读取 PostgreSQL 中的日报和订阅设置,邮件实际发送仍由后续 n8n 工作流完成。
|