File size: 9,001 Bytes
d45a3d8
 
 
 
 
 
 
 
 
 
60f7456
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
---
title: WeRSS
emoji: 🐠
colorFrom: green
colorTo: purple
sdk: docker
pinned: false
license: mit
---


# WeRSS · Hugging Face Docker Space

这个目录用于把 `CaPaCaptain/WeRSS` 部署为 Hugging Face Docker Space。

Dockerfile 不复制 Space 仓库中的业务代码,而是在构建阶段从 GitHub 拉取指定分支或标签,因此 GitHub 仓库更新后,只需在 Hugging Face Space 中执行 **Factory rebuild** 即可重新构建。

> 本目录需要作为 Hugging Face Space 仓库的根目录使用。若它保存在主 GitHub 仓库的 `huggingface/` 子目录中,请把该目录内的 `Dockerfile` 和 `README.md` 同步到 Space 根目录。

## 1. 部署架构

- 源代码:`https://github.com/CaPaCaptain/WeRSS`
- Hugging Face SDK:Docker
- 对外端口:`7860`
- 后端:FastAPI
- 前端:已编译 Vue 静态文件
- 默认数据库:SQLite
- 持久化路径:`/data`
- API 前缀:`/api/v1/wx`
- Swagger:`/api/docs`
- ReDoc:`/api/redoc`
- OpenAPI:`/api/openapi.json`

## 2. 创建 Hugging Face Space

1. 在 Hugging Face 新建 Space。
2. SDK 选择 **Docker**3. 建议第一次部署使用 **Private Space**4. 把本目录中的 `Dockerfile``README.md` 上传到 Space 根目录。
5. 在 Space 的 **Settings → Variables and secrets** 配置下列项目。
6. 如需持久保存数据库、微信公众号授权、配置、导出文件和缓存,请把持久化存储或 Storage Bucket 挂载到 `/data`7. 保存配置后执行 **Factory rebuild**## 3. 构建参数与 GitHub 配置

### Variables

| 名称 | 建议值 | 是否必须 | 说明 |
|---|---|---:|---|
| `REPO_URL` | `https://github.com/CaPaCaptain/WeRSS.git` | 是 | 构建时拉取的 GitHub 仓库 |
| `REPO_REF` | `main` | 是 | 分支、标签或可解析的 Git 引用 |
| `USERNAME` | `admin` | 建议 | 初始化管理员用户名 |
| `WEB_NAME` | `WeRSS微信公众号订阅助手` | 否 | 前端显示名称 |
| `RSS_BASE_URL` | `https://你的-space.hf.space/` | 建议 | RSS 对外基础地址,建议以 `/` 结尾 |
| `ENABLE_JOB` | `True` | 否 | 是否启动定时更新任务 |
| `THREADS` | `1` | 建议 | 免费 CPU Space 建议保持 1 |
| `BROWSER_TYPE` | `webkit` | 建议 | Playwright 浏览器类型 |
| `GATHER_CONTENT` | `False` | 否 | 是否采集正文 |
| `GATHER_MODEL` | `web` | 否 | 采集模式:`web``api``app` |
| `GATHER_CONTENT_AUTO_CHECK` | `True` | 否 | 是否自动检查未采集正文 |
| `MAX_PAGE` | `5` | 否 | 首次添加公众号时最多采集页数 |
| `TOKEN_EXPIRE_MINUTES` | `4320` | 否 | Web 登录 Token 有效期 |
| `LOG_LEVEL` | `INFO` | 否 | 日志级别 |
| `PROXY_ENABLED` | `False` | 否 | 是否启用代理 |
| `PROXY_HTTP_URL` | 空 | 否 | HTTP 或 SOCKS5 代理地址 |
| `PROXY_DENO_URL` | 空 | 否 | Deno 代理地址 |

Dockerfile 已设置以下默认值,通常不用在 Space 中重复配置:

```text
PORT=7860
DB=sqlite:////data/db.db
THREADS=1
AUTO_RELOAD=False
```

### Secrets

| 名称 | 是否必须 | 说明 |
|---|---:|---|
| `GITHUB_TOKEN` | 私有仓库必须 | GitHub fine-grained PAT;只授予该仓库 `Contents: Read-only` |
| `PASSWORD` | 强烈建议 | 初始化管理员密码;不要使用上游默认密码 |
| `SECRET_KEY` | 强烈建议 | JWT 签名密钥,建议使用至少 32 字节随机值 |
| `REDIS_SERVER_PASSWORD` | 可选 | 内置 Redis 密码 |
| `DINGDING_WEBHOOK` | 可选 | 钉钉通知 Webhook |
| `WECHAT_WEBHOOK` | 可选 | 企业微信通知 Webhook |
| `FEISHU_WEBHOOK` | 可选 | 飞书通知 Webhook |
| `CUSTOM_WEBHOOK` | 可选 | 自定义通知 Webhook |
| `CASCADE_API_KEY` | 可选 | 级联系统 API Key |
| `CASCADE_API_SECRET` | 可选 | 级联系统 API Secret |

生成随机密钥示例:

```bash
openssl rand -base64 48
```

### 私有 GitHub 仓库 Token

建议创建 GitHub fine-grained personal access token:

- Repository access:只选择 `CaPaCaptain/WeRSS`
- Repository permissions:
  - Contents:Read-only
  - Metadata:Read-only
- 不需要写入、Actions 或管理权限

把 Token 保存为 Hugging Face Secret:`GITHUB_TOKEN`。

Dockerfile 通过一次性的 Git HTTP Authorization Header 读取该 Secret;Token 不会写入 Git remote,并会在运行应用前清除 `GITHUB_TOKEN` 环境变量。

## 4. 持久化

WeRSS 默认会写入:

- SQLite 数据库
- 微信公众号授权 Token
- `config.yaml`
- 头像与文章相关文件
- 缓存
- PDF、Markdown 等导出文件
- 自动生成的 JWT Secret(未显式设置 `SECRET_KEY` 时)

Dockerfile 将:

```text
/app/data        → /data
/app/config.yaml → /data/config.yaml
```

没有挂载持久化存储时,Space 重启、休眠或重建后,上述数据可能丢失。

推荐:

- 挂载路径:`/data`
- 数据库:默认 `sqlite:////data/db.db`
- 正式长期运行时可改用外部 PostgreSQL 或 MySQL,并通过 Secret `DB` 设置连接字符串

数据库连接示例:

```text
# PostgreSQL
postgresql://username:password@host:5432/database

# MySQL
mysql+pymysql://username:password@host:3306/we-rss?charset=utf8mb4
```

数据库连接字符串包含密码时,必须使用 **Secret**,不要使用公开 Variable。

## 5. 本地构建测试

### 私有 GitHub 仓库

```bash
printf '%s' 'github_pat_xxx' > .github_token

docker build \
  --secret id=GITHUB_TOKEN,src=.github_token \
  --build-arg REPO_URL=https://github.com/CaPaCaptain/WeRSS.git \
  --build-arg REPO_REF=main \
  -t werss-hf .
```

运行:

```bash
mkdir -p data

docker run --rm \
  --name werss-hf \
  -p 7860:7860 \
  -v "$PWD/data:/data" \
  -e USERNAME=admin \
  -e PASSWORD='请替换为强密码' \
  -e SECRET_KEY='请替换为随机密钥' \
  -e RSS_BASE_URL='http://localhost:7860/' \
  werss-hf
```

访问:

```text
http://localhost:7860/
http://localhost:7860/api/docs
```

### 公开 GitHub 仓库

```bash
docker build \
  --build-arg REPO_URL=https://github.com/CaPaCaptain/WeRSS.git \
  --build-arg REPO_REF=main \
  -t werss-hf .
```

## 6. API 配置

```text
BASE_URL=https://你的-space.hf.space
API_BASE=${BASE_URL}/api/v1/wx
```

Swagger 文档:

```text
${BASE_URL}/api/docs
```

### 获取 Bearer Token

```bash
curl -X POST "${BASE_URL}/api/v1/wx/auth/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "username=admin" \
  --data-urlencode "password=你的管理员密码"
```

验证 Token:

```bash
curl "${BASE_URL}/api/v1/wx/auth/verify" \
  -H "Authorization: Bearer 你的_access_token"
```

### 创建 Access Key

```bash
curl -X POST "${BASE_URL}/api/v1/wx/auth/ak/create" \
  -H "Authorization: Bearer 你的_access_token" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "n8n",
    "description": "供 n8n 工作流调用",
    "permissions": ["article:read", "article:sync"],
    "expires_in_days": 365
  }'
```

其他接口、参数和认证方式以 Swagger `/api/docs` 中当前构建版本为准。

## 7. n8n / Webhook 接入

在 n8n 的 HTTP Request 节点中:

```text
Base URL: https://你的-space.hf.space/api/v1/wx
Authentication: Header Auth
Header: Authorization
Value: Bearer <access_token>
```

建议正式自动化使用 Access Key,而不是长期保存管理员用户名与密码。

通知 Webhook 可通过以下 Secrets 配置:

```text
DINGDING_WEBHOOK
WECHAT_WEBHOOK
FEISHU_WEBHOOK
CUSTOM_WEBHOOK
```

## 8. 更新与版本锁定

### 跟随 GitHub main

```text
REPO_REF=main
```

每次 GitHub 更新后,在 Space 中执行:

```text
Settings → Factory rebuild
```

### 固定版本

生产环境建议把 `REPO_REF` 设置为 Git tag、固定分支或 commit SHA,避免主分支更新造成不可预期变化。

## 9. Hugging Face 兼容处理

此 Dockerfile 在构建时执行以下调整:

1. 将服务端口从上游默认 `8001` 改为 Space 公开端口 `7860`2.`/app/data``/app/config.yaml` 持久化到 `/data`3. 把点号环境变量名转换为下划线形式,例如:
   - `GATHER.CONTENT``GATHER_CONTENT`
   - `CACHE.DIR``CACHE_DIR`
   - `WEBHOOK.CONTENT_FORMAT``WEBHOOK_CONTENT_FORMAT`
4. 移除启动时打印全部环境变量的代码,防止 Secrets 出现在日志中。
5. 使用一次性 Git Authorization Header 拉取私有仓库,不把 Token 写入 remote,并在运行前清除 `GITHUB_TOKEN`## 10. 注意事项

- 微信公众号采集依赖浏览器自动化,镜像较大,首次构建时间和内存占用会高于普通 FastAPI 应用。
- 免费 Space 可能休眠;休眠期间定时更新任务不会持续执行。
- 微信接口可能受出口 IP、地区、风控和授权状态影响。
- 公网部署前必须更改管理员密码并设置 `SECRET_KEY`- 建议初期使用 Private Space,确认登录、授权、RSS 与 API 均正常后再决定是否公开。
- 不要在 README、Dockerfile、GitHub 提交或 Space Variables 中硬编码密码、Token、Webhook 或数据库凭据。