Files
Mebbling/README.md
T

126 lines
5.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Mebbling
自架的 Memos 公開貼文 Hub。將朋友各自 Memos 中的公開貼文集中展示,同時保留 Hub 內的留言、表情回應與發文功能。
目前開發版本:`v0.2.0`(尚未發布)。版本變更請見 [CHANGELOG.md](CHANGELOG.md)。
## 功能
- 匯入多個 Memos 來源的 `PUBLIC` 貼文、標籤與附件。
- 圖片在首頁與文章頁直接顯示;點擊後以站內全螢幕燈箱檢視。
- Hub 使用者可留言、表情回應,並可將新貼文推送到已連接的 Memos。
- 同一個「Memos 網址 + Memos 帳號」只建立一個共享來源,避免重複同步及重複貼文。
- 使用者可加入共享來源並手動同步或發文;僅來源建立者能管理 webhook URL。
- Webhook URL 採不可猜測的隨機密鑰路徑、雜湊保存與簡易速率限制。
- 控制台會顯示最近一次收到 webhook 的時間及最後同步時間。
- 來源建立者可重新命名、停用、刪除或轉移所有權;共享成員可自行離開來源。
- 同步工作具去重、重試、觸發來源與歷史紀錄;管理員可集中檢視異常。
- 內建 SQLite 與附件備份腳本,以及可追蹤的 schema migration。
## 快速啟動(WSLDocker
```bash
cp .env.example .env
# 編輯 .env,至少設定 SESSION_SECRET、TOKEN_ENCRYPTION_KEY、ADMIN_USERNAME、ADMIN_PASSWORD
docker compose up --build -d
```
預設網址為 [http://localhost:8088](http://localhost:8088)。停止服務:
```bash
docker compose down
```
查看服務狀態與日誌:
```bash
docker compose ps
docker compose logs -f web worker
```
## 環境變數
`.env.example` 為範本。正式環境請更換所有 secret,且不要將 `.env` 加入 Git。
| 變數 | 用途 |
| --- | --- |
| `SESSION_SECRET` | 登入 session 的簽章密鑰。請使用長隨機字串。 |
| `TOKEN_ENCRYPTION_KEY` | Memos Token 的 AES-256-GCM 加密金鑰,必須為 64 個十六進位字元。 |
| `ADMIN_USERNAME` / `ADMIN_PASSWORD` | 首次啟動時建立的管理員帳號。 |
| `NEXT_PUBLIC_APP_URL` | Hub 的對外 HTTPS 網址,例如 `https://mebbling.example.com`。Webhook URL 以此組成。 |
| `UPLOAD_MAX_BYTES` | Hub 發文上傳附件的單檔上限,預設 10 MiB。 |
| `SYNC_INTERVAL_MINUTES` | 背景校正同步的間隔,預設 60 分鐘。 |
| `SEED_MEMOS_*` | 選填;首次啟動時自動建立管理員的第一個 Memos 來源。 |
## 系統架構
```mermaid
flowchart LR
Visitor[訪客/Hub 使用者] --> Web[Next.js Web\nport 8088]
Web --> DB[(SQLite\ndata/hub.db)]
Web --> Uploads[附件\npublic/uploads]
Memos[Memos 來源] -->|Webhook| Web
Web -->|建立同步工作| Jobs[同步佇列\nsync_jobs]
Worker[背景 Worker] --> Jobs
Worker --> DB
Worker <-->|Memos API| Memos
Worker --> Uploads
```
Web 接收使用者操作和 webhook,將同步需求寫入 SQLite 的 `sync_jobs`。背景 Worker 每 5 秒處理一項工作,負責:
- **Pull**:從 Memos 取得公開貼文,更新 Hub 鏡像;已刪除或非公開的遠端貼文會在 Hub 隱藏。
- **Push**:把 Hub 建立的貼文與本機附件上傳/回寫到選定的 Memos 來源。
- **排程校正**:依 `SYNC_INTERVAL_MINUTES` 定期建立 Pull 工作,避免 webhook 遺漏造成資料不同步。
## Webhook 設定與驗證
1. 來源建立者登入「控制台」。
2. 在來源卡片按「產生 webhook URL」,立即複製完整網址。
3. 在該 Memos 帳號的 webhook 設定中貼上網址。
4. 在 Memos 發布或更新一篇公開貼文。
5. 回到 Hub:顯示「最近收到」代表 Hub 確實收到 webhook;「上次同步」更新則代表同步已完成。
網址格式如下;`來源 ID``隨機密鑰` 都由系統產生,請勿自行修改:
```text
https://你的網域/api/sync/webhook/來源ID/隨機密鑰
```
重新產生 webhook URL 會立即使舊 URL 失效。共享來源的其他成員可查看接收狀態,但沒有產生或輪替密鑰的權限。
## 專案結構
```text
.
├── app/ # Next.js App Router:頁面、元件與 API
│ ├── api/ # 登入、來源、發文、同步、webhook 等路由
│ ├── components/ # 可重用 UI,例如附件圖片燈箱
│ ├── dashboard/ # 來源管理、發文與 webhook 控制台
│ ├── posts/[id]/ # 單篇貼文頁
│ ├── page.tsx # 公開貼文首頁
│ ├── layout.tsx # 全站版型與導覽
│ └── styles.css # 全站樣式
├── lib/ # 共用伺服器邏輯
│ ├── auth.ts # Session 與權限
│ ├── crypto.ts # Token 加解密
│ ├── db.ts # SQLite schema 與輕量遷移
│ ├── memos.ts # Memos API 封裝
│ ├── webhook.ts # Webhook 密鑰產生、雜湊與驗證
│ └── rate-limit.ts # Webhook 簡易速率限制
├── worker/ # 背景同步 worker
├── public/uploads/ # Hub 上傳附件的持久化資料
├── data/ # SQLite 資料庫持久化資料
├── Dockerfile # WebWorker 共用映像檔
├── docker-compose.yml # web + worker 服務與 volume 掛載
└── .env.example # 環境變數範本
```
`data/``public/uploads/` 是正式資料,備份時請一併備份。`.next/``node_modules/` 是可重新產生的建置/依賴資料,不需備份。
備份、還原及資料庫 migration 的操作請見 [維運文件](docs/OPERATIONS.md)。
## 正式部署
`NEXT_PUBLIC_APP_URL` 設成實際 HTTPS 網域,並以反向代理將該網域導向 Web 容器的 3000 連接埠(或主機的 8088 對應埠)。務必確保外部可連到 webhook URL,否則仍會由定期校正同步補回資料,但不會即時更新。